mirror of
				https://gitee.com/gitea/gitea
				synced 2025-11-04 16:40:24 +08:00 
			
		
		
		
	Replace util.SliceXxx  with slices.Xxx  (#26958)
				
					
				
			This commit is contained in:
		@@ -6,6 +6,7 @@ package actions
 | 
				
			|||||||
import (
 | 
					import (
 | 
				
			||||||
	"context"
 | 
						"context"
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
 | 
						"slices"
 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -350,7 +351,7 @@ func UpdateRun(ctx context.Context, run *ActionRun, cols ...string) error {
 | 
				
			|||||||
		// It's impossible that the run is not found, since Gitea never deletes runs.
 | 
							// 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 {
 | 
							if run.RepoID == 0 {
 | 
				
			||||||
			run, err = GetRunByID(ctx, run.ID)
 | 
								run, err = GetRunByID(ctx, run.ID)
 | 
				
			||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,6 +6,7 @@ package actions
 | 
				
			|||||||
import (
 | 
					import (
 | 
				
			||||||
	"context"
 | 
						"context"
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
 | 
						"slices"
 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"code.gitea.io/gitea/models/db"
 | 
						"code.gitea.io/gitea/models/db"
 | 
				
			||||||
@@ -107,11 +108,11 @@ func UpdateRunJob(ctx context.Context, job *ActionRunJob, cond builder.Cond, col
 | 
				
			|||||||
		return 0, err
 | 
							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
 | 
							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 the status of job changes to waiting again, increase tasks version.
 | 
				
			||||||
		if err := IncreaseTaskVersion(ctx, job.OwnerID, job.RepoID); err != nil {
 | 
							if err := IncreaseTaskVersion(ctx, job.OwnerID, job.RepoID); err != nil {
 | 
				
			||||||
			return 0, err
 | 
								return 0, err
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,6 +7,7 @@ import (
 | 
				
			|||||||
	"context"
 | 
						"context"
 | 
				
			||||||
	"errors"
 | 
						"errors"
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
 | 
						"slices"
 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"code.gitea.io/gitea/models/db"
 | 
						"code.gitea.io/gitea/models/db"
 | 
				
			||||||
@@ -435,7 +436,7 @@ func updateTeamWhitelist(ctx context.Context, repo *repo_model.Repository, curre
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	whitelist = make([]int64, 0, len(teams))
 | 
						whitelist = make([]int64, 0, len(teams))
 | 
				
			||||||
	for i := range 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)
 | 
								whitelist = append(whitelist, teams[i].ID)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,6 +8,7 @@ import (
 | 
				
			|||||||
	"context"
 | 
						"context"
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"regexp"
 | 
						"regexp"
 | 
				
			||||||
 | 
						"slices"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"code.gitea.io/gitea/models/db"
 | 
						"code.gitea.io/gitea/models/db"
 | 
				
			||||||
	project_model "code.gitea.io/gitea/models/project"
 | 
						project_model "code.gitea.io/gitea/models/project"
 | 
				
			||||||
@@ -605,7 +606,7 @@ func IsUserParticipantsOfIssue(user *user_model.User, issue *Issue) bool {
 | 
				
			|||||||
		log.Error(err.Error())
 | 
							log.Error(err.Error())
 | 
				
			||||||
		return false
 | 
							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.
 | 
					// DependencyInfo represents high level information about an issue which is a dependency of another issue.
 | 
				
			||||||
@@ -630,7 +631,7 @@ func (issue *Issue) GetParticipantIDsByIssue(ctx context.Context) ([]int64, erro
 | 
				
			|||||||
		Find(&userIDs); err != nil {
 | 
							Find(&userIDs); err != nil {
 | 
				
			||||||
		return nil, fmt.Errorf("get poster IDs: %w", err)
 | 
							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 append(userIDs, issue.PosterID), nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return userIDs, nil
 | 
						return userIDs, nil
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,6 +6,7 @@ package repo
 | 
				
			|||||||
import (
 | 
					import (
 | 
				
			||||||
	"context"
 | 
						"context"
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
 | 
						"slices"
 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"code.gitea.io/gitea/models/db"
 | 
						"code.gitea.io/gitea/models/db"
 | 
				
			||||||
@@ -176,7 +177,7 @@ func (cfg *ActionsConfig) ToString() string {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (cfg *ActionsConfig) IsWorkflowDisabled(file string) bool {
 | 
					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) {
 | 
					func (cfg *ActionsConfig) DisableWorkflow(file string) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,6 +7,7 @@ import (
 | 
				
			|||||||
	"context"
 | 
						"context"
 | 
				
			||||||
	"os"
 | 
						"os"
 | 
				
			||||||
	"runtime/pprof"
 | 
						"runtime/pprof"
 | 
				
			||||||
 | 
						"slices"
 | 
				
			||||||
	"sync/atomic"
 | 
						"sync/atomic"
 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -20,7 +21,6 @@ import (
 | 
				
			|||||||
	"code.gitea.io/gitea/modules/process"
 | 
						"code.gitea.io/gitea/modules/process"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/queue"
 | 
						"code.gitea.io/gitea/modules/queue"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/setting"
 | 
						"code.gitea.io/gitea/modules/setting"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/util"
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var (
 | 
					var (
 | 
				
			||||||
@@ -54,22 +54,22 @@ func index(ctx context.Context, indexer internal.Indexer, repoID int64) error {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// skip forks from being indexed if unit is not present
 | 
						// 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
 | 
							return nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// skip mirrors from being indexed if unit is not present
 | 
						// 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
 | 
							return nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// skip templates from being indexed if unit is not present
 | 
						// 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
 | 
							return nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// skip regular repos from being indexed if unit is not present
 | 
						// 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
 | 
							return nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,6 +10,7 @@ package tests
 | 
				
			|||||||
import (
 | 
					import (
 | 
				
			||||||
	"context"
 | 
						"context"
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
 | 
						"slices"
 | 
				
			||||||
	"testing"
 | 
						"testing"
 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -457,7 +458,7 @@ var cases = []*testIndexerCase{
 | 
				
			|||||||
				assert.Contains(t, data[v.ID].MentionIDs, int64(1))
 | 
									assert.Contains(t, data[v.ID].MentionIDs, int64(1))
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			assert.Equal(t, countIndexerData(data, func(v *internal.IndexerData) bool {
 | 
								assert.Equal(t, countIndexerData(data, func(v *internal.IndexerData) bool {
 | 
				
			||||||
				return util.SliceContains(v.MentionIDs, 1)
 | 
									return slices.Contains(v.MentionIDs, 1)
 | 
				
			||||||
			}), result.Total)
 | 
								}), result.Total)
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
@@ -478,7 +479,7 @@ var cases = []*testIndexerCase{
 | 
				
			|||||||
				assert.Contains(t, data[v.ID].ReviewedIDs, int64(1))
 | 
									assert.Contains(t, data[v.ID].ReviewedIDs, int64(1))
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			assert.Equal(t, countIndexerData(data, func(v *internal.IndexerData) bool {
 | 
								assert.Equal(t, countIndexerData(data, func(v *internal.IndexerData) bool {
 | 
				
			||||||
				return util.SliceContains(v.ReviewedIDs, 1)
 | 
									return slices.Contains(v.ReviewedIDs, 1)
 | 
				
			||||||
			}), result.Total)
 | 
								}), result.Total)
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
@@ -499,7 +500,7 @@ var cases = []*testIndexerCase{
 | 
				
			|||||||
				assert.Contains(t, data[v.ID].ReviewRequestedIDs, int64(1))
 | 
									assert.Contains(t, data[v.ID].ReviewRequestedIDs, int64(1))
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			assert.Equal(t, countIndexerData(data, func(v *internal.IndexerData) bool {
 | 
								assert.Equal(t, countIndexerData(data, func(v *internal.IndexerData) bool {
 | 
				
			||||||
				return util.SliceContains(v.ReviewRequestedIDs, 1)
 | 
									return slices.Contains(v.ReviewRequestedIDs, 1)
 | 
				
			||||||
			}), result.Total)
 | 
								}), result.Total)
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
@@ -520,7 +521,7 @@ var cases = []*testIndexerCase{
 | 
				
			|||||||
				assert.Contains(t, data[v.ID].SubscriberIDs, int64(1))
 | 
									assert.Contains(t, data[v.ID].SubscriberIDs, int64(1))
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			assert.Equal(t, countIndexerData(data, func(v *internal.IndexerData) bool {
 | 
								assert.Equal(t, countIndexerData(data, func(v *internal.IndexerData) bool {
 | 
				
			||||||
				return util.SliceContains(v.SubscriberIDs, 1)
 | 
									return slices.Contains(v.SubscriberIDs, 1)
 | 
				
			||||||
			}), result.Total)
 | 
								}), result.Total)
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,11 +4,11 @@
 | 
				
			|||||||
package templates
 | 
					package templates
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"slices"
 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"code.gitea.io/gitea/modules/assetfs"
 | 
						"code.gitea.io/gitea/modules/assetfs"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/setting"
 | 
						"code.gitea.io/gitea/modules/setting"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/util"
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func AssetFS() *assetfs.LayeredFS {
 | 
					func AssetFS() *assetfs.LayeredFS {
 | 
				
			||||||
@@ -24,7 +24,7 @@ func ListWebTemplateAssetNames(assets *assetfs.LayeredFS) ([]string, error) {
 | 
				
			|||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							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")
 | 
							return strings.HasPrefix(file, "mail/") || !strings.HasSuffix(file, ".tmpl")
 | 
				
			||||||
	}), nil
 | 
						}), nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -34,7 +34,7 @@ func ListMailTemplateAssetNames(assets *assetfs.LayeredFS) ([]string, error) {
 | 
				
			|||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							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")
 | 
							return !strings.HasPrefix(file, "mail/") || !strings.HasSuffix(file, ".tmpl")
 | 
				
			||||||
	}), nil
 | 
						}), nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,37 +1,21 @@
 | 
				
			|||||||
// Copyright 2022 The Gitea Authors. All rights reserved.
 | 
					// Copyright 2022 The Gitea Authors. All rights reserved.
 | 
				
			||||||
// SPDX-License-Identifier: MIT
 | 
					// 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
 | 
					package util
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import "strings"
 | 
					import (
 | 
				
			||||||
 | 
						"slices"
 | 
				
			||||||
// SliceContains returns true if the target exists in the slice.
 | 
						"strings"
 | 
				
			||||||
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.
 | 
					// SliceContainsString sequential searches if string exists in slice.
 | 
				
			||||||
func SliceContainsString(slice []string, target string, insensitive ...bool) bool {
 | 
					func SliceContainsString(slice []string, target string, insensitive ...bool) bool {
 | 
				
			||||||
	if len(insensitive) != 0 && insensitive[0] {
 | 
						if len(insensitive) != 0 && insensitive[0] {
 | 
				
			||||||
		target = strings.ToLower(target)
 | 
							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.
 | 
					// SliceSortedEqual returns true if the two slices will be equal when they get sorted.
 | 
				
			||||||
@@ -57,34 +41,7 @@ func SliceSortedEqual[T comparable](s1, s2 []T) bool {
 | 
				
			|||||||
	return true
 | 
						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.
 | 
					// SliceRemoveAll removes all the target elements from the slice.
 | 
				
			||||||
func SliceRemoveAll[T comparable](slice []T, target T) []T {
 | 
					func SliceRemoveAll[T comparable](slice []T, target T) []T {
 | 
				
			||||||
	return SliceRemoveAllFunc(slice, func(t T) bool { return t == target })
 | 
						return slices.DeleteFunc(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]
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,20 +9,6 @@ import (
 | 
				
			|||||||
	"github.com/stretchr/testify/assert"
 | 
						"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) {
 | 
					func TestSliceContainsString(t *testing.T) {
 | 
				
			||||||
	assert.True(t, SliceContainsString([]string{"c", "b", "a", "b"}, "a"))
 | 
						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"}, "b"))
 | 
				
			||||||
@@ -54,25 +40,6 @@ func TestSliceSortedEqual(t *testing.T) {
 | 
				
			|||||||
	assert.False(t, SliceSortedEqual([]int{2, 0, 0, 3}, []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) {
 | 
					func TestSliceRemoveAll(t *testing.T) {
 | 
				
			||||||
	assert.ElementsMatch(t, []int{2, 2, 3}, SliceRemoveAll([]int{2, 0, 2, 3}, 0))
 | 
						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))
 | 
						assert.ElementsMatch(t, []int{0, 3}, SliceRemoveAll([]int{2, 0, 2, 3}, 2))
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -16,6 +16,7 @@ import (
 | 
				
			|||||||
	"net/http"
 | 
						"net/http"
 | 
				
			||||||
	"path"
 | 
						"path"
 | 
				
			||||||
	"regexp"
 | 
						"regexp"
 | 
				
			||||||
 | 
						"slices"
 | 
				
			||||||
	"strconv"
 | 
						"strconv"
 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
@@ -265,7 +266,7 @@ func verifyDataOld(signature, data []byte, pub *rsa.PublicKey) error {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if !util.SliceEqual(out[skip:], data) {
 | 
						if !slices.Equal(out[skip:], data) {
 | 
				
			||||||
		return fmt.Errorf("could not verify signature")
 | 
							return fmt.Errorf("could not verify signature")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,6 +7,7 @@ package repo
 | 
				
			|||||||
import (
 | 
					import (
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"net/http"
 | 
						"net/http"
 | 
				
			||||||
 | 
						"slices"
 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -235,7 +236,7 @@ func CreateUserRepo(ctx *context.APIContext, owner *user_model.User, opt api.Cre
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// If the readme template does not exist, a 400 will be returned.
 | 
						// 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))
 | 
							ctx.Error(http.StatusBadRequest, "", fmt.Errorf("readme template does not exist, available templates: %v", repo_module.Readmes))
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -12,6 +12,7 @@ import (
 | 
				
			|||||||
	"math/big"
 | 
						"math/big"
 | 
				
			||||||
	"net/http"
 | 
						"net/http"
 | 
				
			||||||
	"net/url"
 | 
						"net/url"
 | 
				
			||||||
 | 
						"slices"
 | 
				
			||||||
	"sort"
 | 
						"sort"
 | 
				
			||||||
	"strconv"
 | 
						"strconv"
 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
@@ -3628,7 +3629,7 @@ func issuePosters(ctx *context.Context, isPullList bool) {
 | 
				
			|||||||
	if search == "" && ctx.Doer != nil {
 | 
						if search == "" && ctx.Doer != nil {
 | 
				
			||||||
		// the returned posters slice only contains limited number of users,
 | 
							// 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
 | 
							// 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)
 | 
								posters = append(posters, ctx.Doer)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,6 +8,7 @@ import (
 | 
				
			|||||||
	"errors"
 | 
						"errors"
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"net/http"
 | 
						"net/http"
 | 
				
			||||||
 | 
						"slices"
 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"code.gitea.io/gitea/models"
 | 
						"code.gitea.io/gitea/models"
 | 
				
			||||||
@@ -659,7 +660,7 @@ func GetBranchesList(ctx *context.Context) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	resp := &branchTagSearchResponse{}
 | 
						resp := &branchTagSearchResponse{}
 | 
				
			||||||
	// always put default branch on the top if it exists
 | 
						// 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 = util.SliceRemoveAll(branches, ctx.Repo.Repository.DefaultBranch)
 | 
				
			||||||
		branches = append([]string{ctx.Repo.Repository.DefaultBranch}, branches...)
 | 
							branches = append([]string{ctx.Repo.Repository.DefaultBranch}, branches...)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -693,7 +694,7 @@ func PrepareBranchList(ctx *context.Context) {
 | 
				
			|||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	// always put default branch on the top if it exists
 | 
						// 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 = util.SliceRemoveAll(brs, ctx.Repo.Repository.DefaultBranch)
 | 
				
			||||||
		brs = append([]string{ctx.Repo.Repository.DefaultBranch}, brs...)
 | 
							brs = append([]string{ctx.Repo.Repository.DefaultBranch}, brs...)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,6 +14,7 @@ import (
 | 
				
			|||||||
	"net/http"
 | 
						"net/http"
 | 
				
			||||||
	"net/url"
 | 
						"net/url"
 | 
				
			||||||
	"path"
 | 
						"path"
 | 
				
			||||||
 | 
						"slices"
 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -370,7 +371,7 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry, treeLink, rawLink st
 | 
				
			|||||||
		if workFlowErr != nil {
 | 
							if workFlowErr != nil {
 | 
				
			||||||
			ctx.Data["FileError"] = ctx.Locale.Tr("actions.runs.invalid_workflow_helper", workFlowErr.Error())
 | 
								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 {
 | 
							if data, err := blob.GetBlobContent(setting.UI.MaxDisplayFileSize); err == nil {
 | 
				
			||||||
			_, warnings := issue_model.GetCodeOwnersFromContent(ctx, data)
 | 
								_, warnings := issue_model.GetCodeOwnersFromContent(ctx, data)
 | 
				
			||||||
			if len(warnings) > 0 {
 | 
								if len(warnings) > 0 {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,6 +9,7 @@ import (
 | 
				
			|||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"net/http"
 | 
						"net/http"
 | 
				
			||||||
	"regexp"
 | 
						"regexp"
 | 
				
			||||||
 | 
						"slices"
 | 
				
			||||||
	"sort"
 | 
						"sort"
 | 
				
			||||||
	"strconv"
 | 
						"strconv"
 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
@@ -290,7 +291,7 @@ func Milestones(ctx *context.Context) {
 | 
				
			|||||||
	if len(repoIDs) == 0 {
 | 
						if len(repoIDs) == 0 {
 | 
				
			||||||
		repoIDs = showRepoIds.Values()
 | 
							repoIDs = showRepoIds.Values()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	repoIDs = util.SliceRemoveAllFunc(repoIDs, func(v int64) bool {
 | 
						repoIDs = slices.DeleteFunc(repoIDs, func(v int64) bool {
 | 
				
			||||||
		return !showRepoIds.Contains(v)
 | 
							return !showRepoIds.Contains(v)
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -534,7 +535,7 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) {
 | 
				
			|||||||
	// Gets set when clicking filters on the issues overview page.
 | 
						// Gets set when clicking filters on the issues overview page.
 | 
				
			||||||
	selectedRepoIDs := getRepoIDs(ctx.FormString("repos"))
 | 
						selectedRepoIDs := getRepoIDs(ctx.FormString("repos"))
 | 
				
			||||||
	// Remove repo IDs that are not accessible to the user.
 | 
						// 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)
 | 
							return !accessibleRepos.Contains(v)
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
	if len(selectedRepoIDs) > 0 {
 | 
						if len(selectedRepoIDs) > 0 {
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user