aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cmd/admin.go2
-rw-r--r--cmd/dump.go11
-rw-r--r--models/asymkey/ssh_key.go8
-rw-r--r--models/auth/oauth2.go4
-rw-r--r--models/git/branches.go8
-rw-r--r--models/issues/assignees.go2
-rw-r--r--models/issues/issue.go4
-rw-r--r--models/org_team.go21
-rw-r--r--models/user.go21
-rw-r--r--modules/repository/init.go6
-rw-r--r--modules/util/compare.go92
-rw-r--r--modules/util/slice.go91
-rw-r--r--modules/util/slice_test.go88
-rw-r--r--routers/api/v1/utils/hook.go34
-rw-r--r--routers/web/repo/issue.go4
-rw-r--r--routers/web/repo/webhook.go2
-rw-r--r--routers/web/user/notification.go2
-rw-r--r--routers/web/user/setting/profile.go2
-rw-r--r--services/auth/source/ldap/source_search.go2
-rw-r--r--services/auth/source/smtp/source_authenticate.go2
-rw-r--r--services/wiki/wiki.go2
-rw-r--r--tests/integration/api_repo_teams_test.go2
22 files changed, 228 insertions, 182 deletions
diff --git a/cmd/admin.go b/cmd/admin.go
index 7463b21d81..a662011f9c 100644
--- a/cmd/admin.go
+++ b/cmd/admin.go
@@ -950,7 +950,7 @@ func parseSMTPConfig(c *cli.Context, conf *smtp.Source) error {
if c.IsSet("auth-type") {
conf.Auth = c.String("auth-type")
validAuthTypes := []string{"PLAIN", "LOGIN", "CRAM-MD5"}
- if !contains(validAuthTypes, strings.ToUpper(c.String("auth-type"))) {
+ if !util.SliceContainsString(validAuthTypes, strings.ToUpper(c.String("auth-type"))) {
return errors.New("Auth must be one of PLAIN/LOGIN/CRAM-MD5")
}
conf.Auth = c.String("auth-type")
diff --git a/cmd/dump.go b/cmd/dump.go
index 672a8cdc9c..f40ddbac23 100644
--- a/cmd/dump.go
+++ b/cmd/dump.go
@@ -409,15 +409,6 @@ func runDump(ctx *cli.Context) error {
return nil
}
-func contains(slice []string, s string) bool {
- for _, v := range slice {
- if v == s {
- return true
- }
- }
- return false
-}
-
// addRecursiveExclude zips absPath to specified insidePath inside writer excluding excludeAbsPath
func addRecursiveExclude(w archiver.Writer, insidePath, absPath string, excludeAbsPath []string, verbose bool) error {
absPath, err := filepath.Abs(absPath)
@@ -438,7 +429,7 @@ func addRecursiveExclude(w archiver.Writer, insidePath, absPath string, excludeA
currentAbsPath := path.Join(absPath, file.Name())
currentInsidePath := path.Join(insidePath, file.Name())
if file.IsDir() {
- if !contains(excludeAbsPath, currentAbsPath) {
+ if !util.SliceContainsString(excludeAbsPath, currentAbsPath) {
if err := addFile(w, currentInsidePath, currentAbsPath, false); err != nil {
return err
}
diff --git a/models/asymkey/ssh_key.go b/models/asymkey/ssh_key.go
index 4d6ae8103c..8d84c2f7dc 100644
--- a/models/asymkey/ssh_key.go
+++ b/models/asymkey/ssh_key.go
@@ -409,14 +409,14 @@ func SynchronizePublicKeys(usr *user_model.User, s *auth.Source, sshPublicKeys [
sshKeySplit := strings.Split(v, " ")
if len(sshKeySplit) > 1 {
key := strings.Join(sshKeySplit[:2], " ")
- if !util.ExistsInSlice(key, providedKeys) {
+ if !util.SliceContainsString(providedKeys, key) {
providedKeys = append(providedKeys, key)
}
}
}
// Check if Public Key sync is needed
- if util.IsEqualSlice(giteaKeys, providedKeys) {
+ if util.SliceSortedEqual(giteaKeys, providedKeys) {
log.Trace("synchronizePublicKeys[%s]: Public Keys are already in sync for %s (Source:%v/DB:%v)", s.Name, usr.Name, len(providedKeys), len(giteaKeys))
return false
}
@@ -425,7 +425,7 @@ func SynchronizePublicKeys(usr *user_model.User, s *auth.Source, sshPublicKeys [
// Add new Public SSH Keys that doesn't already exist in DB
var newKeys []string
for _, key := range providedKeys {
- if !util.ExistsInSlice(key, giteaKeys) {
+ if !util.SliceContainsString(giteaKeys, key) {
newKeys = append(newKeys, key)
}
}
@@ -436,7 +436,7 @@ func SynchronizePublicKeys(usr *user_model.User, s *auth.Source, sshPublicKeys [
// Mark keys from DB that no longer exist in the source for deletion
var giteaKeysToDelete []string
for _, giteaKey := range giteaKeys {
- if !util.ExistsInSlice(giteaKey, providedKeys) {
+ if !util.SliceContainsString(providedKeys, giteaKey) {
log.Trace("synchronizePublicKeys[%s]: Marking Public SSH Key for deletion for user %s: %v", s.Name, usr.Name, giteaKey)
giteaKeysToDelete = append(giteaKeysToDelete, giteaKey)
}
diff --git a/models/auth/oauth2.go b/models/auth/oauth2.go
index 8e5a003d19..09d4bfc4ea 100644
--- a/models/auth/oauth2.go
+++ b/models/auth/oauth2.go
@@ -69,13 +69,13 @@ func (app *OAuth2Application) ContainsRedirectURI(redirectURI string) bool {
if ip != nil && ip.IsLoopback() {
// strip port
uri.Host = uri.Hostname()
- if util.IsStringInSlice(uri.String(), app.RedirectURIs, true) {
+ if util.SliceContainsString(app.RedirectURIs, uri.String(), true) {
return true
}
}
}
}
- return util.IsStringInSlice(redirectURI, app.RedirectURIs, true)
+ return util.SliceContainsString(app.RedirectURIs, redirectURI, true)
}
// Base32 characters, but lowercased.
diff --git a/models/git/branches.go b/models/git/branches.go
index 2becbc3d13..5ec9fc1735 100644
--- a/models/git/branches.go
+++ b/models/git/branches.go
@@ -342,7 +342,7 @@ func IsProtectedBranch(ctx context.Context, repoID int64, branchName string) (bo
// updateApprovalWhitelist checks whether the user whitelist changed and returns a whitelist with
// the users from newWhitelist which have explicit read or write access to the repo.
func updateApprovalWhitelist(ctx context.Context, repo *repo_model.Repository, currentWhitelist, newWhitelist []int64) (whitelist []int64, err error) {
- hasUsersChanged := !util.IsSliceInt64Eq(currentWhitelist, newWhitelist)
+ hasUsersChanged := !util.SliceSortedEqual(currentWhitelist, newWhitelist)
if !hasUsersChanged {
return currentWhitelist, nil
}
@@ -363,7 +363,7 @@ func updateApprovalWhitelist(ctx context.Context, repo *repo_model.Repository, c
// updateUserWhitelist checks whether the user whitelist changed and returns a whitelist with
// the users from newWhitelist which have write access to the repo.
func updateUserWhitelist(ctx context.Context, repo *repo_model.Repository, currentWhitelist, newWhitelist []int64) (whitelist []int64, err error) {
- hasUsersChanged := !util.IsSliceInt64Eq(currentWhitelist, newWhitelist)
+ hasUsersChanged := !util.SliceSortedEqual(currentWhitelist, newWhitelist)
if !hasUsersChanged {
return currentWhitelist, nil
}
@@ -392,7 +392,7 @@ func updateUserWhitelist(ctx context.Context, repo *repo_model.Repository, curre
// updateTeamWhitelist checks whether the team whitelist changed and returns a whitelist with
// the teams from newWhitelist which have write access to the repo.
func updateTeamWhitelist(ctx context.Context, repo *repo_model.Repository, currentWhitelist, newWhitelist []int64) (whitelist []int64, err error) {
- hasTeamsChanged := !util.IsSliceInt64Eq(currentWhitelist, newWhitelist)
+ hasTeamsChanged := !util.SliceSortedEqual(currentWhitelist, newWhitelist)
if !hasTeamsChanged {
return currentWhitelist, nil
}
@@ -404,7 +404,7 @@ func updateTeamWhitelist(ctx context.Context, repo *repo_model.Repository, curre
whitelist = make([]int64, 0, len(teams))
for i := range teams {
- if util.IsInt64InSlice(teams[i].ID, newWhitelist) {
+ if util.SliceContains(newWhitelist, teams[i].ID) {
whitelist = append(whitelist, teams[i].ID)
}
}
diff --git a/models/issues/assignees.go b/models/issues/assignees.go
index 159086bd01..16f675a83f 100644
--- a/models/issues/assignees.go
+++ b/models/issues/assignees.go
@@ -155,7 +155,7 @@ func MakeIDsFromAPIAssigneesToAdd(ctx context.Context, oneAssignee string, multi
var requestAssignees []string
// Keeping the old assigning method for compatibility reasons
- if oneAssignee != "" && !util.IsStringInSlice(oneAssignee, multipleAssignees) {
+ if oneAssignee != "" && !util.SliceContainsString(multipleAssignees, oneAssignee) {
requestAssignees = append(requestAssignees, oneAssignee)
}
diff --git a/models/issues/issue.go b/models/issues/issue.go
index 417d6a1557..4a8ab06824 100644
--- a/models/issues/issue.go
+++ b/models/issues/issue.go
@@ -1529,7 +1529,7 @@ func IsUserParticipantsOfIssue(user *user_model.User, issue *Issue) bool {
log.Error(err.Error())
return false
}
- return util.IsInt64InSlice(user.ID, userIDs)
+ return util.SliceContains(userIDs, user.ID)
}
// UpdateIssueMentions updates issue-user relations for mentioned users.
@@ -2023,7 +2023,7 @@ func (issue *Issue) GetParticipantIDsByIssue(ctx context.Context) ([]int64, erro
Find(&userIDs); err != nil {
return nil, fmt.Errorf("get poster IDs: %w", err)
}
- if !util.IsInt64InSlice(issue.PosterID, userIDs) {
+ if !util.SliceContains(userIDs, issue.PosterID) {
return append(userIDs, issue.PosterID), nil
}
return userIDs, nil
diff --git a/models/org_team.go b/models/org_team.go
index b3ee842c1f..2bbf1d8d8c 100644
--- a/models/org_team.go
+++ b/models/org_team.go
@@ -398,20 +398,13 @@ func DeleteTeam(t *organization.Team) error {
return fmt.Errorf("findProtectedBranches: %w", err)
}
for _, p := range protections {
- var matched1, matched2, matched3 bool
- if len(p.WhitelistTeamIDs) != 0 {
- p.WhitelistTeamIDs, matched1 = util.RemoveIDFromList(
- p.WhitelistTeamIDs, t.ID)
- }
- if len(p.ApprovalsWhitelistTeamIDs) != 0 {
- p.ApprovalsWhitelistTeamIDs, matched2 = util.RemoveIDFromList(
- p.ApprovalsWhitelistTeamIDs, t.ID)
- }
- if len(p.MergeWhitelistTeamIDs) != 0 {
- p.MergeWhitelistTeamIDs, matched3 = util.RemoveIDFromList(
- p.MergeWhitelistTeamIDs, t.ID)
- }
- if matched1 || matched2 || matched3 {
+ lenIDs, lenApprovalIDs, lenMergeIDs := len(p.WhitelistTeamIDs), len(p.ApprovalsWhitelistTeamIDs), len(p.MergeWhitelistTeamIDs)
+ p.WhitelistTeamIDs = util.SliceRemoveAll(p.WhitelistTeamIDs, t.ID)
+ p.ApprovalsWhitelistTeamIDs = util.SliceRemoveAll(p.ApprovalsWhitelistTeamIDs, t.ID)
+ p.MergeWhitelistTeamIDs = util.SliceRemoveAll(p.MergeWhitelistTeamIDs, t.ID)
+ if lenIDs != len(p.WhitelistTeamIDs) ||
+ lenApprovalIDs != len(p.ApprovalsWhitelistTeamIDs) ||
+ lenMergeIDs != len(p.MergeWhitelistTeamIDs) {
if _, err = sess.ID(p.ID).Cols(
"whitelist_team_i_ds",
"merge_whitelist_team_i_ds",
diff --git a/models/user.go b/models/user.go
index 715d0e3866..10282d0db4 100644
--- a/models/user.go
+++ b/models/user.go
@@ -141,20 +141,13 @@ func DeleteUser(ctx context.Context, u *user_model.User, purge bool) (err error)
break
}
for _, p := range protections {
- var matched1, matched2, matched3 bool
- if len(p.WhitelistUserIDs) != 0 {
- p.WhitelistUserIDs, matched1 = util.RemoveIDFromList(
- p.WhitelistUserIDs, u.ID)
- }
- if len(p.ApprovalsWhitelistUserIDs) != 0 {
- p.ApprovalsWhitelistUserIDs, matched2 = util.RemoveIDFromList(
- p.ApprovalsWhitelistUserIDs, u.ID)
- }
- if len(p.MergeWhitelistUserIDs) != 0 {
- p.MergeWhitelistUserIDs, matched3 = util.RemoveIDFromList(
- p.MergeWhitelistUserIDs, u.ID)
- }
- if matched1 || matched2 || matched3 {
+ lenIDs, lenApprovalIDs, lenMergeIDs := len(p.WhitelistUserIDs), len(p.ApprovalsWhitelistUserIDs), len(p.MergeWhitelistUserIDs)
+ p.WhitelistUserIDs = util.SliceRemoveAll(p.WhitelistUserIDs, u.ID)
+ p.ApprovalsWhitelistUserIDs = util.SliceRemoveAll(p.ApprovalsWhitelistUserIDs, u.ID)
+ p.MergeWhitelistUserIDs = util.SliceRemoveAll(p.MergeWhitelistUserIDs, u.ID)
+ if lenIDs != len(p.WhitelistUserIDs) ||
+ lenApprovalIDs != len(p.ApprovalsWhitelistUserIDs) ||
+ lenMergeIDs != len(p.MergeWhitelistUserIDs) {
if _, err = e.ID(p.ID).Cols(
"whitelist_user_i_ds",
"merge_whitelist_user_i_ds",
diff --git a/modules/repository/init.go b/modules/repository/init.go
index 59284a5baf..2b0d0be7bc 100644
--- a/modules/repository/init.go
+++ b/modules/repository/init.go
@@ -170,7 +170,7 @@ func LoadRepoConfig() {
}
for _, f := range customFiles {
- if !util.IsStringInSlice(f, files, true) {
+ if !util.SliceContainsString(files, f, true) {
files = append(files, f)
}
}
@@ -200,12 +200,12 @@ func LoadRepoConfig() {
// Filter out invalid names and promote preferred licenses.
sortedLicenses := make([]string, 0, len(Licenses))
for _, name := range setting.Repository.PreferredLicenses {
- if util.IsStringInSlice(name, Licenses, true) {
+ if util.SliceContainsString(Licenses, name, true) {
sortedLicenses = append(sortedLicenses, name)
}
}
for _, name := range Licenses {
- if !util.IsStringInSlice(name, setting.Repository.PreferredLicenses, true) {
+ if !util.SliceContainsString(setting.Repository.PreferredLicenses, name, true) {
sortedLicenses = append(sortedLicenses, name)
}
}
diff --git a/modules/util/compare.go b/modules/util/compare.go
deleted file mode 100644
index 9ac778dfd3..0000000000
--- a/modules/util/compare.go
+++ /dev/null
@@ -1,92 +0,0 @@
-// Copyright 2017 The Gitea Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-package util
-
-import (
- "sort"
- "strings"
-)
-
-// Int64Slice attaches the methods of Interface to []int64, sorting in increasing order.
-type Int64Slice []int64
-
-func (p Int64Slice) Len() int { return len(p) }
-func (p Int64Slice) Less(i, j int) bool { return p[i] < p[j] }
-func (p Int64Slice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
-
-// IsSliceInt64Eq returns if the two slice has the same elements but different sequences.
-func IsSliceInt64Eq(a, b []int64) bool {
- if len(a) != len(b) {
- return false
- }
- sort.Sort(Int64Slice(a))
- sort.Sort(Int64Slice(b))
- for i := 0; i < len(a); i++ {
- if a[i] != b[i] {
- return false
- }
- }
- return true
-}
-
-// ExistsInSlice returns true if string exists in slice.
-func ExistsInSlice(target string, slice []string) bool {
- i := sort.Search(len(slice),
- func(i int) bool { return slice[i] == target })
- return i < len(slice)
-}
-
-// IsStringInSlice sequential searches if string exists in slice.
-func IsStringInSlice(target string, slice []string, insensitive ...bool) bool {
- caseInsensitive := false
- if len(insensitive) != 0 && insensitive[0] {
- caseInsensitive = true
- target = strings.ToLower(target)
- }
-
- for i := 0; i < len(slice); i++ {
- if caseInsensitive {
- if strings.ToLower(slice[i]) == target {
- return true
- }
- } else {
- if slice[i] == target {
- return true
- }
- }
- }
- return false
-}
-
-// IsInt64InSlice sequential searches if int64 exists in slice.
-func IsInt64InSlice(target int64, slice []int64) bool {
- for i := 0; i < len(slice); i++ {
- if slice[i] == target {
- return true
- }
- }
- return false
-}
-
-// IsEqualSlice returns true if slices are equal.
-func IsEqualSlice(target, source []string) bool {
- if len(target) != len(source) {
- return false
- }
-
- if (target == nil) != (source == nil) {
- return false
- }
-
- sort.Strings(target)
- sort.Strings(source)
-
- for i, v := range target {
- if v != source[i] {
- return false
- }
- }
-
- return true
-}
diff --git a/modules/util/slice.go b/modules/util/slice.go
index 17345cbc49..74356f5496 100644
--- a/modules/util/slice.go
+++ b/modules/util/slice.go
@@ -1,17 +1,90 @@
// 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
-// RemoveIDFromList removes the given ID from the slice, if found.
-// It does not preserve order, and assumes the ID is unique.
-func RemoveIDFromList(list []int64, id int64) ([]int64, bool) {
- n := len(list) - 1
- for i, item := range list {
- if item == id {
- list[i] = list[n]
- return list[:n], true
+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
+}
+
+// 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 SliceContains(slice, target)
+}
+
+// SliceSortedEqual returns true if the two slices will be equal when they get sorted.
+// It doesn't require that the slices have been sorted, and it doesn't sort them either.
+func SliceSortedEqual[T comparable](s1, s2 []T) bool {
+ if len(s1) != len(s2) {
+ return false
+ }
+
+ counts := make(map[T]int, len(s1))
+ for _, v := range s1 {
+ counts[v]++
+ }
+ for _, v := range s2 {
+ counts[v]--
+ }
+
+ for _, v := range counts {
+ if v != 0 {
+ return false
+ }
+ }
+ 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 list, false
+ return slice[:idx]
}
diff --git a/modules/util/slice_test.go b/modules/util/slice_test.go
new file mode 100644
index 0000000000..b0b771a79a
--- /dev/null
+++ b/modules/util/slice_test.go
@@ -0,0 +1,88 @@
+// Copyright 2023 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package util
+
+import (
+ "testing"
+
+ "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.True(t, SliceContainsString([]string{"c", "b", "a", "b"}, "A", true))
+ assert.True(t, SliceContainsString([]string{"C", "B", "A", "B"}, "a", true))
+
+ assert.False(t, SliceContainsString([]string{"c", "b", "a", "b"}, "z"))
+ assert.False(t, SliceContainsString([]string{"c", "b", "a", "b"}, "A"))
+ assert.False(t, SliceContainsString([]string{}, "a"))
+ assert.False(t, SliceContainsString(nil, "a"))
+}
+
+func TestSliceSortedEqual(t *testing.T) {
+ assert.True(t, SliceSortedEqual([]int{2, 0, 2, 3}, []int{2, 0, 2, 3}))
+ assert.True(t, SliceSortedEqual([]int{3, 0, 2, 2}, []int{2, 0, 2, 3}))
+ assert.True(t, SliceSortedEqual([]int{}, []int{}))
+ assert.True(t, SliceSortedEqual([]int(nil), nil))
+ assert.True(t, SliceSortedEqual([]int(nil), []int{}))
+ assert.True(t, SliceSortedEqual([]int{}, []int{}))
+
+ assert.True(t, SliceSortedEqual([]string{"2", "0", "2", "3"}, []string{"2", "0", "2", "3"}))
+ assert.True(t, SliceSortedEqual([]float64{2, 0, 2, 3}, []float64{2, 0, 2, 3}))
+ assert.True(t, SliceSortedEqual([]bool{false, true, false}, []bool{false, true, false}))
+
+ assert.False(t, SliceSortedEqual([]int{2, 0, 2}, []int{2, 0, 2, 3}))
+ assert.False(t, SliceSortedEqual([]int{}, []int{2, 0, 2, 3}))
+ assert.False(t, SliceSortedEqual(nil, []int{2, 0, 2, 3}))
+ assert.False(t, SliceSortedEqual([]int{2, 0, 2, 4}, []int{2, 0, 2, 3}))
+ 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.Equal(t, SliceRemoveAll([]int{2, 0, 2, 3}, 0), []int{2, 2, 3})
+ assert.Equal(t, SliceRemoveAll([]int{2, 0, 2, 3}, 2), []int{0, 3})
+ assert.Equal(t, SliceRemoveAll([]int{0, 0, 0, 0}, 0), []int{})
+ assert.Equal(t, SliceRemoveAll([]int{2, 0, 2, 3}, 4), []int{2, 0, 2, 3})
+ assert.Equal(t, SliceRemoveAll([]int{}, 0), []int{})
+ assert.Equal(t, SliceRemoveAll([]int(nil), 0), []int(nil))
+ assert.Equal(t, SliceRemoveAll([]int{}, 0), []int{})
+
+ assert.Equal(t, SliceRemoveAll([]string{"2", "0", "2", "3"}, "0"), []string{"2", "2", "3"})
+ assert.Equal(t, SliceRemoveAll([]float64{2, 0, 2, 3}, 0), []float64{2, 2, 3})
+ assert.Equal(t, SliceRemoveAll([]bool{false, true, false}, true), []bool{false, false})
+}
diff --git a/routers/api/v1/utils/hook.go b/routers/api/v1/utils/hook.go
index 065b761adb..44fba22b5a 100644
--- a/routers/api/v1/utils/hook.go
+++ b/routers/api/v1/utils/hook.go
@@ -107,11 +107,11 @@ func toAPIHook(ctx *context.APIContext, repoLink string, hook *webhook.Webhook)
}
func issuesHook(events []string, event string) bool {
- return util.IsStringInSlice(event, events, true) || util.IsStringInSlice(string(webhook_module.HookEventIssues), events, true)
+ return util.SliceContainsString(events, event, true) || util.SliceContainsString(events, string(webhook_module.HookEventIssues), true)
}
func pullHook(events []string, event string) bool {
- return util.IsStringInSlice(event, events, true) || util.IsStringInSlice(string(webhook_module.HookEventPullRequest), events, true)
+ return util.SliceContainsString(events, event, true) || util.SliceContainsString(events, string(webhook_module.HookEventPullRequest), true)
}
// addHook add the hook specified by `form`, `orgID` and `repoID`. If there is
@@ -130,15 +130,15 @@ func addHook(ctx *context.APIContext, form *api.CreateHookOption, orgID, repoID
HookEvent: &webhook_module.HookEvent{
ChooseEvents: true,
HookEvents: webhook_module.HookEvents{
- Create: util.IsStringInSlice(string(webhook_module.HookEventCreate), form.Events, true),
- Delete: util.IsStringInSlice(string(webhook_module.HookEventDelete), form.Events, true),
- Fork: util.IsStringInSlice(string(webhook_module.HookEventFork), form.Events, true),
+ Create: util.SliceContainsString(form.Events, string(webhook_module.HookEventCreate), true),
+ Delete: util.SliceContainsString(form.Events, string(webhook_module.HookEventDelete), true),
+ Fork: util.SliceContainsString(form.Events, string(webhook_module.HookEventFork), true),
Issues: issuesHook(form.Events, "issues_only"),
IssueAssign: issuesHook(form.Events, string(webhook_module.HookEventIssueAssign)),
IssueLabel: issuesHook(form.Events, string(webhook_module.HookEventIssueLabel)),
IssueMilestone: issuesHook(form.Events, string(webhook_module.HookEventIssueMilestone)),
IssueComment: issuesHook(form.Events, string(webhook_module.HookEventIssueComment)),
- Push: util.IsStringInSlice(string(webhook_module.HookEventPush), form.Events, true),
+ Push: util.SliceContainsString(form.Events, string(webhook_module.HookEventPush), true),
PullRequest: pullHook(form.Events, "pull_request_only"),
PullRequestAssign: pullHook(form.Events, string(webhook_module.HookEventPullRequestAssign)),
PullRequestLabel: pullHook(form.Events, string(webhook_module.HookEventPullRequestLabel)),
@@ -146,9 +146,9 @@ func addHook(ctx *context.APIContext, form *api.CreateHookOption, orgID, repoID
PullRequestComment: pullHook(form.Events, string(webhook_module.HookEventPullRequestComment)),
PullRequestReview: pullHook(form.Events, "pull_request_review"),
PullRequestSync: pullHook(form.Events, string(webhook_module.HookEventPullRequestSync)),
- Wiki: util.IsStringInSlice(string(webhook_module.HookEventWiki), form.Events, true),
- Repository: util.IsStringInSlice(string(webhook_module.HookEventRepository), form.Events, true),
- Release: util.IsStringInSlice(string(webhook_module.HookEventRelease), form.Events, true),
+ Wiki: util.SliceContainsString(form.Events, string(webhook_module.HookEventWiki), true),
+ Repository: util.SliceContainsString(form.Events, string(webhook_module.HookEventRepository), true),
+ Release: util.SliceContainsString(form.Events, string(webhook_module.HookEventRelease), true),
},
BranchFilter: form.BranchFilter,
},
@@ -277,14 +277,14 @@ func editHook(ctx *context.APIContext, form *api.EditHookOption, w *webhook.Webh
w.PushOnly = false
w.SendEverything = false
w.ChooseEvents = true
- w.Create = util.IsStringInSlice(string(webhook_module.HookEventCreate), form.Events, true)
- w.Push = util.IsStringInSlice(string(webhook_module.HookEventPush), form.Events, true)
- w.Create = util.IsStringInSlice(string(webhook_module.HookEventCreate), form.Events, true)
- w.Delete = util.IsStringInSlice(string(webhook_module.HookEventDelete), form.Events, true)
- w.Fork = util.IsStringInSlice(string(webhook_module.HookEventFork), form.Events, true)
- w.Repository = util.IsStringInSlice(string(webhook_module.HookEventRepository), form.Events, true)
- w.Wiki = util.IsStringInSlice(string(webhook_module.HookEventWiki), form.Events, true)
- w.Release = util.IsStringInSlice(string(webhook_module.HookEventRelease), form.Events, true)
+ w.Create = util.SliceContainsString(form.Events, string(webhook_module.HookEventCreate), true)
+ w.Push = util.SliceContainsString(form.Events, string(webhook_module.HookEventPush), true)
+ w.Create = util.SliceContainsString(form.Events, string(webhook_module.HookEventCreate), true)
+ w.Delete = util.SliceContainsString(form.Events, string(webhook_module.HookEventDelete), true)
+ w.Fork = util.SliceContainsString(form.Events, string(webhook_module.HookEventFork), true)
+ w.Repository = util.SliceContainsString(form.Events, string(webhook_module.HookEventRepository), true)
+ w.Wiki = util.SliceContainsString(form.Events, string(webhook_module.HookEventWiki), true)
+ w.Release = util.SliceContainsString(form.Events, string(webhook_module.HookEventRelease), true)
w.BranchFilter = form.BranchFilter
err := w.SetHeaderAuthorization(form.AuthorizationHeader)
diff --git a/routers/web/repo/issue.go b/routers/web/repo/issue.go
index 07dd98f1a5..f037c771d4 100644
--- a/routers/web/repo/issue.go
+++ b/routers/web/repo/issue.go
@@ -139,7 +139,7 @@ func issues(ctx *context.Context, milestoneID, projectID int64, isPullOption uti
viewType := ctx.FormString("type")
sortType := ctx.FormString("sort")
types := []string{"all", "your_repositories", "assigned", "created_by", "mentioned", "review_requested"}
- if !util.IsStringInSlice(viewType, types, true) {
+ if !util.SliceContainsString(types, viewType, true) {
viewType = "all"
}
@@ -3087,7 +3087,7 @@ func updateAttachments(ctx *context.Context, item interface{}, files []string) e
return fmt.Errorf("unknown Type: %T", content)
}
for i := 0; i < len(attachments); i++ {
- if util.IsStringInSlice(attachments[i].UUID, files) {
+ if util.SliceContainsString(files, attachments[i].UUID) {
continue
}
if err := repo_model.DeleteAttachment(attachments[i], true); err != nil {
diff --git a/routers/web/repo/webhook.go b/routers/web/repo/webhook.go
index bf56e3d0bd..96261af674 100644
--- a/routers/web/repo/webhook.go
+++ b/routers/web/repo/webhook.go
@@ -110,7 +110,7 @@ func getOrgRepoCtx(ctx *context.Context) (*orgRepoCtx, error) {
func checkHookType(ctx *context.Context) string {
hookType := strings.ToLower(ctx.Params(":type"))
- if !util.IsStringInSlice(hookType, setting.Webhook.Types, true) {
+ if !util.SliceContainsString(setting.Webhook.Types, hookType, true) {
ctx.NotFound("checkHookType", nil)
return ""
}
diff --git a/routers/web/user/notification.go b/routers/web/user/notification.go
index b21d52bbfd..e96b3dd27a 100644
--- a/routers/web/user/notification.go
+++ b/routers/web/user/notification.go
@@ -214,7 +214,7 @@ func NotificationSubscriptions(ctx *context.Context) {
ctx.Data["SortType"] = sortType
state := ctx.FormString("state")
- if !util.IsStringInSlice(state, []string{"all", "open", "closed"}, true) {
+ if !util.SliceContainsString([]string{"all", "open", "closed"}, state, true) {
state = "all"
}
ctx.Data["State"] = state
diff --git a/routers/web/user/setting/profile.go b/routers/web/user/setting/profile.go
index ef45ad8a86..dac00850b1 100644
--- a/routers/web/user/setting/profile.go
+++ b/routers/web/user/setting/profile.go
@@ -413,7 +413,7 @@ func UpdateUserLang(ctx *context.Context) {
ctx.Data["PageIsSettingsAppearance"] = true
if len(form.Language) != 0 {
- if !util.IsStringInSlice(form.Language, setting.Langs) {
+ if !util.SliceContainsString(setting.Langs, form.Language) {
ctx.Flash.Error(ctx.Tr("settings.update_language_not_found", form.Language))
ctx.Redirect(setting.AppSubURL + "/user/settings/appearance")
return
diff --git a/services/auth/source/ldap/source_search.go b/services/auth/source/ldap/source_search.go
index 6b6b56db2f..68ebba3917 100644
--- a/services/auth/source/ldap/source_search.go
+++ b/services/auth/source/ldap/source_search.go
@@ -246,7 +246,7 @@ func (source *Source) getMappedMemberships(l *ldap.Conn, uid string) (map[string
membershipsToAdd := map[string][]string{}
membershipsToRemove := map[string][]string{}
for group, memberships := range ldapGroupsToTeams {
- isUserInGroup := util.IsStringInSlice(group, usersLdapGroups)
+ isUserInGroup := util.SliceContainsString(usersLdapGroups, group)
if isUserInGroup {
for org, teams := range memberships {
membershipsToAdd[org] = teams
diff --git a/services/auth/source/smtp/source_authenticate.go b/services/auth/source/smtp/source_authenticate.go
index 00aaa8e084..36b351198a 100644
--- a/services/auth/source/smtp/source_authenticate.go
+++ b/services/auth/source/smtp/source_authenticate.go
@@ -23,7 +23,7 @@ func (source *Source) Authenticate(user *user_model.User, userName, password str
idx := strings.Index(userName, "@")
if idx == -1 {
return nil, user_model.ErrUserNotExist{Name: userName}
- } else if !util.IsStringInSlice(userName[idx+1:], strings.Split(source.AllowedDomains, ","), true) {
+ } else if !util.SliceContainsString(strings.Split(source.AllowedDomains, ","), userName[idx+1:], true) {
return nil, user_model.ErrUserNotExist{Name: userName}
}
}
diff --git a/services/wiki/wiki.go b/services/wiki/wiki.go
index e483416fda..e5cb2db02b 100644
--- a/services/wiki/wiki.go
+++ b/services/wiki/wiki.go
@@ -35,7 +35,7 @@ const (
)
func nameAllowed(name string) error {
- if util.IsStringInSlice(name, reservedWikiNames) {
+ if util.SliceContainsString(reservedWikiNames, name) {
return repo_model.ErrWikiReservedName{
Title: name,
}
diff --git a/tests/integration/api_repo_teams_test.go b/tests/integration/api_repo_teams_test.go
index e4d054aaf8..102f170d94 100644
--- a/tests/integration/api_repo_teams_test.go
+++ b/tests/integration/api_repo_teams_test.go
@@ -38,7 +38,7 @@ func TestAPIRepoTeams(t *testing.T) {
if assert.Len(t, teams, 2) {
assert.EqualValues(t, "Owners", teams[0].Name)
assert.True(t, teams[0].CanCreateOrgRepo)
- assert.True(t, util.IsEqualSlice(unit.AllUnitKeyNames(), teams[0].Units), fmt.Sprintf("%v == %v", unit.AllUnitKeyNames(), teams[0].Units))
+ assert.True(t, util.SliceSortedEqual(unit.AllUnitKeyNames(), teams[0].Units), fmt.Sprintf("%v == %v", unit.AllUnitKeyNames(), teams[0].Units))
assert.EqualValues(t, "owner", teams[0].Permission)
assert.EqualValues(t, "test_team", teams[1].Name)