migrate some more "OptionalBool" to "Option[bool]" (#29479)
just some refactoring bits towards replacing **util.OptionalBool** with **optional.Option[bool]** --------- Co-authored-by: KN4CK3R <admin@oldschoolhack.me> (cherry picked from commit f6656181e4a07d6c415927220efa2077d509f7c6) Conflicts: models/repo/repo_list_test.go trivial shared fixture count conflicts
This commit is contained in:
		
					parent
					
						
							
								4127fcd608
							
						
					
				
			
			
				commit
				
					
						d3d70198b0
					
				
			
		
					 23 changed files with 183 additions and 174 deletions
				
			
		| 
						 | 
					@ -13,6 +13,7 @@ import (
 | 
				
			||||||
	"code.gitea.io/gitea/models/unit"
 | 
						"code.gitea.io/gitea/models/unit"
 | 
				
			||||||
	user_model "code.gitea.io/gitea/models/user"
 | 
						user_model "code.gitea.io/gitea/models/user"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/container"
 | 
						"code.gitea.io/gitea/modules/container"
 | 
				
			||||||
 | 
						"code.gitea.io/gitea/modules/optional"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/setting"
 | 
						"code.gitea.io/gitea/modules/setting"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/structs"
 | 
						"code.gitea.io/gitea/modules/structs"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/util"
 | 
						"code.gitea.io/gitea/modules/util"
 | 
				
			||||||
| 
						 | 
					@ -125,11 +126,11 @@ type SearchRepoOptions struct {
 | 
				
			||||||
	// None -> include public and private
 | 
						// None -> include public and private
 | 
				
			||||||
	// True -> include just private
 | 
						// True -> include just private
 | 
				
			||||||
	// False -> include just public
 | 
						// False -> include just public
 | 
				
			||||||
	IsPrivate util.OptionalBool
 | 
						IsPrivate optional.Option[bool]
 | 
				
			||||||
	// None -> include collaborative AND non-collaborative
 | 
						// None -> include collaborative AND non-collaborative
 | 
				
			||||||
	// True -> include just collaborative
 | 
						// True -> include just collaborative
 | 
				
			||||||
	// False -> include just non-collaborative
 | 
						// False -> include just non-collaborative
 | 
				
			||||||
	Collaborate util.OptionalBool
 | 
						Collaborate optional.Option[bool]
 | 
				
			||||||
	// What type of unit the user can be collaborative in,
 | 
						// What type of unit the user can be collaborative in,
 | 
				
			||||||
	// it is ignored if Collaborate is False.
 | 
						// it is ignored if Collaborate is False.
 | 
				
			||||||
	// TypeInvalid means any unit type.
 | 
						// TypeInvalid means any unit type.
 | 
				
			||||||
| 
						 | 
					@ -137,19 +138,19 @@ type SearchRepoOptions struct {
 | 
				
			||||||
	// None -> include forks AND non-forks
 | 
						// None -> include forks AND non-forks
 | 
				
			||||||
	// True -> include just forks
 | 
						// True -> include just forks
 | 
				
			||||||
	// False -> include just non-forks
 | 
						// False -> include just non-forks
 | 
				
			||||||
	Fork util.OptionalBool
 | 
						Fork optional.Option[bool]
 | 
				
			||||||
	// None -> include templates AND non-templates
 | 
						// None -> include templates AND non-templates
 | 
				
			||||||
	// True -> include just templates
 | 
						// True -> include just templates
 | 
				
			||||||
	// False -> include just non-templates
 | 
						// False -> include just non-templates
 | 
				
			||||||
	Template util.OptionalBool
 | 
						Template optional.Option[bool]
 | 
				
			||||||
	// None -> include mirrors AND non-mirrors
 | 
						// None -> include mirrors AND non-mirrors
 | 
				
			||||||
	// True -> include just mirrors
 | 
						// True -> include just mirrors
 | 
				
			||||||
	// False -> include just non-mirrors
 | 
						// False -> include just non-mirrors
 | 
				
			||||||
	Mirror util.OptionalBool
 | 
						Mirror optional.Option[bool]
 | 
				
			||||||
	// None -> include archived AND non-archived
 | 
						// None -> include archived AND non-archived
 | 
				
			||||||
	// True -> include just archived
 | 
						// True -> include just archived
 | 
				
			||||||
	// False -> include just non-archived
 | 
						// False -> include just non-archived
 | 
				
			||||||
	Archived util.OptionalBool
 | 
						Archived optional.Option[bool]
 | 
				
			||||||
	// only search topic name
 | 
						// only search topic name
 | 
				
			||||||
	TopicOnly bool
 | 
						TopicOnly bool
 | 
				
			||||||
	// only search repositories with specified primary language
 | 
						// only search repositories with specified primary language
 | 
				
			||||||
| 
						 | 
					@ -159,7 +160,7 @@ type SearchRepoOptions struct {
 | 
				
			||||||
	// None -> include has milestones AND has no milestone
 | 
						// None -> include has milestones AND has no milestone
 | 
				
			||||||
	// True -> include just has milestones
 | 
						// True -> include just has milestones
 | 
				
			||||||
	// False -> include just has no milestone
 | 
						// False -> include just has no milestone
 | 
				
			||||||
	HasMilestones util.OptionalBool
 | 
						HasMilestones optional.Option[bool]
 | 
				
			||||||
	// LowerNames represents valid lower names to restrict to
 | 
						// LowerNames represents valid lower names to restrict to
 | 
				
			||||||
	LowerNames []string
 | 
						LowerNames []string
 | 
				
			||||||
	// When specified true, apply some filters over the conditions:
 | 
						// When specified true, apply some filters over the conditions:
 | 
				
			||||||
| 
						 | 
					@ -359,12 +360,12 @@ func SearchRepositoryCondition(opts *SearchRepoOptions) builder.Cond {
 | 
				
			||||||
			)))
 | 
								)))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if opts.IsPrivate != util.OptionalBoolNone {
 | 
						if opts.IsPrivate.Has() {
 | 
				
			||||||
		cond = cond.And(builder.Eq{"is_private": opts.IsPrivate.IsTrue()})
 | 
							cond = cond.And(builder.Eq{"is_private": opts.IsPrivate.Value()})
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if opts.Template != util.OptionalBoolNone {
 | 
						if opts.Template.Has() {
 | 
				
			||||||
		cond = cond.And(builder.Eq{"is_template": opts.Template == util.OptionalBoolTrue})
 | 
							cond = cond.And(builder.Eq{"is_template": opts.Template.Value()})
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Restrict to starred repositories
 | 
						// Restrict to starred repositories
 | 
				
			||||||
| 
						 | 
					@ -380,11 +381,11 @@ func SearchRepositoryCondition(opts *SearchRepoOptions) builder.Cond {
 | 
				
			||||||
	// Restrict repositories to those the OwnerID owns or contributes to as per opts.Collaborate
 | 
						// Restrict repositories to those the OwnerID owns or contributes to as per opts.Collaborate
 | 
				
			||||||
	if opts.OwnerID > 0 {
 | 
						if opts.OwnerID > 0 {
 | 
				
			||||||
		accessCond := builder.NewCond()
 | 
							accessCond := builder.NewCond()
 | 
				
			||||||
		if opts.Collaborate != util.OptionalBoolTrue {
 | 
							if !opts.Collaborate.Value() {
 | 
				
			||||||
			accessCond = builder.Eq{"owner_id": opts.OwnerID}
 | 
								accessCond = builder.Eq{"owner_id": opts.OwnerID}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if opts.Collaborate != util.OptionalBoolFalse {
 | 
							if opts.Collaborate.ValueOrDefault(true) {
 | 
				
			||||||
			// A Collaboration is:
 | 
								// A Collaboration is:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			collaborateCond := builder.NewCond()
 | 
								collaborateCond := builder.NewCond()
 | 
				
			||||||
| 
						 | 
					@ -472,32 +473,33 @@ func SearchRepositoryCondition(opts *SearchRepoOptions) builder.Cond {
 | 
				
			||||||
			Where(builder.Eq{"language": opts.Language}).And(builder.Eq{"is_primary": true})))
 | 
								Where(builder.Eq{"language": opts.Language}).And(builder.Eq{"is_primary": true})))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if opts.Fork != util.OptionalBoolNone || opts.OnlyShowRelevant {
 | 
						if opts.Fork.Has() || opts.OnlyShowRelevant {
 | 
				
			||||||
		if opts.OnlyShowRelevant && opts.Fork == util.OptionalBoolNone {
 | 
							if opts.OnlyShowRelevant && !opts.Fork.Has() {
 | 
				
			||||||
			cond = cond.And(builder.Eq{"is_fork": false})
 | 
								cond = cond.And(builder.Eq{"is_fork": false})
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			cond = cond.And(builder.Eq{"is_fork": opts.Fork == util.OptionalBoolTrue})
 | 
								cond = cond.And(builder.Eq{"is_fork": opts.Fork.Value()})
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if opts.Mirror != util.OptionalBoolNone {
 | 
						if opts.Mirror.Has() {
 | 
				
			||||||
		cond = cond.And(builder.Eq{"is_mirror": opts.Mirror == util.OptionalBoolTrue})
 | 
							cond = cond.And(builder.Eq{"is_mirror": opts.Mirror.Value()})
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if opts.Actor != nil && opts.Actor.IsRestricted {
 | 
						if opts.Actor != nil && opts.Actor.IsRestricted {
 | 
				
			||||||
		cond = cond.And(AccessibleRepositoryCondition(opts.Actor, unit.TypeInvalid))
 | 
							cond = cond.And(AccessibleRepositoryCondition(opts.Actor, unit.TypeInvalid))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if opts.Archived != util.OptionalBoolNone {
 | 
						if opts.Archived.Has() {
 | 
				
			||||||
		cond = cond.And(builder.Eq{"is_archived": opts.Archived == util.OptionalBoolTrue})
 | 
							cond = cond.And(builder.Eq{"is_archived": opts.Archived.Value()})
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch opts.HasMilestones {
 | 
						if opts.HasMilestones.Has() {
 | 
				
			||||||
	case util.OptionalBoolTrue:
 | 
							if opts.HasMilestones.Value() {
 | 
				
			||||||
			cond = cond.And(builder.Gt{"num_milestones": 0})
 | 
								cond = cond.And(builder.Gt{"num_milestones": 0})
 | 
				
			||||||
	case util.OptionalBoolFalse:
 | 
							} else {
 | 
				
			||||||
			cond = cond.And(builder.Eq{"num_milestones": 0}.Or(builder.IsNull{"num_milestones"}))
 | 
								cond = cond.And(builder.Eq{"num_milestones": 0}.Or(builder.IsNull{"num_milestones"}))
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if opts.OnlyShowRelevant {
 | 
						if opts.OnlyShowRelevant {
 | 
				
			||||||
		// Only show a repo that has at least a topic, an icon, or a description
 | 
							// Only show a repo that has at least a topic, an icon, or a description
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -10,7 +10,7 @@ import (
 | 
				
			||||||
	"code.gitea.io/gitea/models/db"
 | 
						"code.gitea.io/gitea/models/db"
 | 
				
			||||||
	repo_model "code.gitea.io/gitea/models/repo"
 | 
						repo_model "code.gitea.io/gitea/models/repo"
 | 
				
			||||||
	"code.gitea.io/gitea/models/unittest"
 | 
						"code.gitea.io/gitea/models/unittest"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/util"
 | 
						"code.gitea.io/gitea/modules/optional"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/stretchr/testify/assert"
 | 
						"github.com/stretchr/testify/assert"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
| 
						 | 
					@ -27,62 +27,62 @@ func getTestCases() []struct {
 | 
				
			||||||
	}{
 | 
						}{
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			name:  "PublicRepositoriesByName",
 | 
								name:  "PublicRepositoriesByName",
 | 
				
			||||||
			opts:  &repo_model.SearchRepoOptions{Keyword: "big_test_", ListOptions: db.ListOptions{PageSize: 10}, Collaborate: util.OptionalBoolFalse},
 | 
								opts:  &repo_model.SearchRepoOptions{Keyword: "big_test_", ListOptions: db.ListOptions{PageSize: 10}, Collaborate: optional.Some(false)},
 | 
				
			||||||
			count: 7,
 | 
								count: 7,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			name:  "PublicAndPrivateRepositoriesByName",
 | 
								name:  "PublicAndPrivateRepositoriesByName",
 | 
				
			||||||
			opts:  &repo_model.SearchRepoOptions{Keyword: "big_test_", ListOptions: db.ListOptions{Page: 1, PageSize: 10}, Private: true, Collaborate: util.OptionalBoolFalse},
 | 
								opts:  &repo_model.SearchRepoOptions{Keyword: "big_test_", ListOptions: db.ListOptions{Page: 1, PageSize: 10}, Private: true, Collaborate: optional.Some(false)},
 | 
				
			||||||
			count: 14,
 | 
								count: 14,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			name:  "PublicAndPrivateRepositoriesByNameWithPagesizeLimitFirstPage",
 | 
								name:  "PublicAndPrivateRepositoriesByNameWithPagesizeLimitFirstPage",
 | 
				
			||||||
			opts:  &repo_model.SearchRepoOptions{Keyword: "big_test_", ListOptions: db.ListOptions{Page: 1, PageSize: 5}, Private: true, Collaborate: util.OptionalBoolFalse},
 | 
								opts:  &repo_model.SearchRepoOptions{Keyword: "big_test_", ListOptions: db.ListOptions{Page: 1, PageSize: 5}, Private: true, Collaborate: optional.Some(false)},
 | 
				
			||||||
			count: 14,
 | 
								count: 14,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			name:  "PublicAndPrivateRepositoriesByNameWithPagesizeLimitSecondPage",
 | 
								name:  "PublicAndPrivateRepositoriesByNameWithPagesizeLimitSecondPage",
 | 
				
			||||||
			opts:  &repo_model.SearchRepoOptions{Keyword: "big_test_", ListOptions: db.ListOptions{Page: 2, PageSize: 5}, Private: true, Collaborate: util.OptionalBoolFalse},
 | 
								opts:  &repo_model.SearchRepoOptions{Keyword: "big_test_", ListOptions: db.ListOptions{Page: 2, PageSize: 5}, Private: true, Collaborate: optional.Some(false)},
 | 
				
			||||||
			count: 14,
 | 
								count: 14,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			name:  "PublicAndPrivateRepositoriesByNameWithPagesizeLimitThirdPage",
 | 
								name:  "PublicAndPrivateRepositoriesByNameWithPagesizeLimitThirdPage",
 | 
				
			||||||
			opts:  &repo_model.SearchRepoOptions{Keyword: "big_test_", ListOptions: db.ListOptions{Page: 3, PageSize: 5}, Private: true, Collaborate: util.OptionalBoolFalse},
 | 
								opts:  &repo_model.SearchRepoOptions{Keyword: "big_test_", ListOptions: db.ListOptions{Page: 3, PageSize: 5}, Private: true, Collaborate: optional.Some(false)},
 | 
				
			||||||
			count: 14,
 | 
								count: 14,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			name:  "PublicAndPrivateRepositoriesByNameWithPagesizeLimitFourthPage",
 | 
								name:  "PublicAndPrivateRepositoriesByNameWithPagesizeLimitFourthPage",
 | 
				
			||||||
			opts:  &repo_model.SearchRepoOptions{Keyword: "big_test_", ListOptions: db.ListOptions{Page: 3, PageSize: 5}, Private: true, Collaborate: util.OptionalBoolFalse},
 | 
								opts:  &repo_model.SearchRepoOptions{Keyword: "big_test_", ListOptions: db.ListOptions{Page: 3, PageSize: 5}, Private: true, Collaborate: optional.Some(false)},
 | 
				
			||||||
			count: 14,
 | 
								count: 14,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			name:  "PublicRepositoriesOfUser",
 | 
								name:  "PublicRepositoriesOfUser",
 | 
				
			||||||
			opts:  &repo_model.SearchRepoOptions{ListOptions: db.ListOptions{Page: 1, PageSize: 10}, OwnerID: 15, Collaborate: util.OptionalBoolFalse},
 | 
								opts:  &repo_model.SearchRepoOptions{ListOptions: db.ListOptions{Page: 1, PageSize: 10}, OwnerID: 15, Collaborate: optional.Some(false)},
 | 
				
			||||||
			count: 2,
 | 
								count: 2,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			name:  "PublicRepositoriesOfUser2",
 | 
								name:  "PublicRepositoriesOfUser2",
 | 
				
			||||||
			opts:  &repo_model.SearchRepoOptions{ListOptions: db.ListOptions{Page: 1, PageSize: 10}, OwnerID: 18, Collaborate: util.OptionalBoolFalse},
 | 
								opts:  &repo_model.SearchRepoOptions{ListOptions: db.ListOptions{Page: 1, PageSize: 10}, OwnerID: 18, Collaborate: optional.Some(false)},
 | 
				
			||||||
			count: 0,
 | 
								count: 0,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			name:  "PublicRepositoriesOfOrg3",
 | 
								name:  "PublicRepositoriesOfOrg3",
 | 
				
			||||||
			opts:  &repo_model.SearchRepoOptions{ListOptions: db.ListOptions{Page: 1, PageSize: 10}, OwnerID: 20, Collaborate: util.OptionalBoolFalse},
 | 
								opts:  &repo_model.SearchRepoOptions{ListOptions: db.ListOptions{Page: 1, PageSize: 10}, OwnerID: 20, Collaborate: optional.Some(false)},
 | 
				
			||||||
			count: 2,
 | 
								count: 2,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			name:  "PublicAndPrivateRepositoriesOfUser",
 | 
								name:  "PublicAndPrivateRepositoriesOfUser",
 | 
				
			||||||
			opts:  &repo_model.SearchRepoOptions{ListOptions: db.ListOptions{Page: 1, PageSize: 10}, OwnerID: 15, Private: true, Collaborate: util.OptionalBoolFalse},
 | 
								opts:  &repo_model.SearchRepoOptions{ListOptions: db.ListOptions{Page: 1, PageSize: 10}, OwnerID: 15, Private: true, Collaborate: optional.Some(false)},
 | 
				
			||||||
			count: 4,
 | 
								count: 4,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			name:  "PublicAndPrivateRepositoriesOfUser2",
 | 
								name:  "PublicAndPrivateRepositoriesOfUser2",
 | 
				
			||||||
			opts:  &repo_model.SearchRepoOptions{ListOptions: db.ListOptions{Page: 1, PageSize: 10}, OwnerID: 18, Private: true, Collaborate: util.OptionalBoolFalse},
 | 
								opts:  &repo_model.SearchRepoOptions{ListOptions: db.ListOptions{Page: 1, PageSize: 10}, OwnerID: 18, Private: true, Collaborate: optional.Some(false)},
 | 
				
			||||||
			count: 0,
 | 
								count: 0,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			name:  "PublicAndPrivateRepositoriesOfOrg3",
 | 
								name:  "PublicAndPrivateRepositoriesOfOrg3",
 | 
				
			||||||
			opts:  &repo_model.SearchRepoOptions{ListOptions: db.ListOptions{Page: 1, PageSize: 10}, OwnerID: 20, Private: true, Collaborate: util.OptionalBoolFalse},
 | 
								opts:  &repo_model.SearchRepoOptions{ListOptions: db.ListOptions{Page: 1, PageSize: 10}, OwnerID: 20, Private: true, Collaborate: optional.Some(false)},
 | 
				
			||||||
			count: 4,
 | 
								count: 4,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
| 
						 | 
					@ -117,32 +117,32 @@ func getTestCases() []struct {
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			name:  "PublicRepositoriesOfOrganization",
 | 
								name:  "PublicRepositoriesOfOrganization",
 | 
				
			||||||
			opts:  &repo_model.SearchRepoOptions{ListOptions: db.ListOptions{Page: 1, PageSize: 10}, OwnerID: 17, Collaborate: util.OptionalBoolFalse},
 | 
								opts:  &repo_model.SearchRepoOptions{ListOptions: db.ListOptions{Page: 1, PageSize: 10}, OwnerID: 17, Collaborate: optional.Some(false)},
 | 
				
			||||||
			count: 1,
 | 
								count: 1,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			name:  "PublicAndPrivateRepositoriesOfOrganization",
 | 
								name:  "PublicAndPrivateRepositoriesOfOrganization",
 | 
				
			||||||
			opts:  &repo_model.SearchRepoOptions{ListOptions: db.ListOptions{Page: 1, PageSize: 10}, OwnerID: 17, Private: true, Collaborate: util.OptionalBoolFalse},
 | 
								opts:  &repo_model.SearchRepoOptions{ListOptions: db.ListOptions{Page: 1, PageSize: 10}, OwnerID: 17, Private: true, Collaborate: optional.Some(false)},
 | 
				
			||||||
			count: 2,
 | 
								count: 2,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			name:  "AllPublic/PublicRepositoriesByName",
 | 
								name:  "AllPublic/PublicRepositoriesByName",
 | 
				
			||||||
			opts:  &repo_model.SearchRepoOptions{Keyword: "big_test_", ListOptions: db.ListOptions{PageSize: 10}, AllPublic: true, Collaborate: util.OptionalBoolFalse},
 | 
								opts:  &repo_model.SearchRepoOptions{Keyword: "big_test_", ListOptions: db.ListOptions{PageSize: 10}, AllPublic: true, Collaborate: optional.Some(false)},
 | 
				
			||||||
			count: 7,
 | 
								count: 7,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			name:  "AllPublic/PublicAndPrivateRepositoriesByName",
 | 
								name:  "AllPublic/PublicAndPrivateRepositoriesByName",
 | 
				
			||||||
			opts:  &repo_model.SearchRepoOptions{Keyword: "big_test_", ListOptions: db.ListOptions{Page: 1, PageSize: 10}, Private: true, AllPublic: true, Collaborate: util.OptionalBoolFalse},
 | 
								opts:  &repo_model.SearchRepoOptions{Keyword: "big_test_", ListOptions: db.ListOptions{Page: 1, PageSize: 10}, Private: true, AllPublic: true, Collaborate: optional.Some(false)},
 | 
				
			||||||
			count: 14,
 | 
								count: 14,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			name:  "AllPublic/PublicRepositoriesOfUserIncludingCollaborative",
 | 
								name:  "AllPublic/PublicRepositoriesOfUserIncludingCollaborative",
 | 
				
			||||||
			opts:  &repo_model.SearchRepoOptions{ListOptions: db.ListOptions{Page: 1, PageSize: 10}, OwnerID: 15, AllPublic: true, Template: util.OptionalBoolFalse},
 | 
								opts:  &repo_model.SearchRepoOptions{ListOptions: db.ListOptions{Page: 1, PageSize: 10}, OwnerID: 15, AllPublic: true, Template: optional.Some(false)},
 | 
				
			||||||
			count: 34,
 | 
								count: 34,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			name:  "AllPublic/PublicAndPrivateRepositoriesOfUserIncludingCollaborative",
 | 
								name:  "AllPublic/PublicAndPrivateRepositoriesOfUserIncludingCollaborative",
 | 
				
			||||||
			opts:  &repo_model.SearchRepoOptions{ListOptions: db.ListOptions{Page: 1, PageSize: 10}, OwnerID: 15, Private: true, AllPublic: true, AllLimited: true, Template: util.OptionalBoolFalse},
 | 
								opts:  &repo_model.SearchRepoOptions{ListOptions: db.ListOptions{Page: 1, PageSize: 10}, OwnerID: 15, Private: true, AllPublic: true, AllLimited: true, Template: optional.Some(false)},
 | 
				
			||||||
			count: 39,
 | 
								count: 39,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
| 
						 | 
					@ -157,12 +157,12 @@ func getTestCases() []struct {
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			name:  "AllPublic/PublicRepositoriesOfOrganization",
 | 
								name:  "AllPublic/PublicRepositoriesOfOrganization",
 | 
				
			||||||
			opts:  &repo_model.SearchRepoOptions{ListOptions: db.ListOptions{Page: 1, PageSize: 10}, OwnerID: 17, AllPublic: true, Collaborate: util.OptionalBoolFalse, Template: util.OptionalBoolFalse},
 | 
								opts:  &repo_model.SearchRepoOptions{ListOptions: db.ListOptions{Page: 1, PageSize: 10}, OwnerID: 17, AllPublic: true, Collaborate: optional.Some(false), Template: optional.Some(false)},
 | 
				
			||||||
			count: 34,
 | 
								count: 34,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			name:  "AllTemplates",
 | 
								name:  "AllTemplates",
 | 
				
			||||||
			opts:  &repo_model.SearchRepoOptions{ListOptions: db.ListOptions{Page: 1, PageSize: 10}, Template: util.OptionalBoolTrue},
 | 
								opts:  &repo_model.SearchRepoOptions{ListOptions: db.ListOptions{Page: 1, PageSize: 10}, Template: optional.Some(true)},
 | 
				
			||||||
			count: 2,
 | 
								count: 2,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
| 
						 | 
					@ -190,7 +190,7 @@ func TestSearchRepository(t *testing.T) {
 | 
				
			||||||
			PageSize: 10,
 | 
								PageSize: 10,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		Keyword:     "repo_12",
 | 
							Keyword:     "repo_12",
 | 
				
			||||||
		Collaborate: util.OptionalBoolFalse,
 | 
							Collaborate: optional.Some(false),
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	assert.NoError(t, err)
 | 
						assert.NoError(t, err)
 | 
				
			||||||
| 
						 | 
					@ -205,7 +205,7 @@ func TestSearchRepository(t *testing.T) {
 | 
				
			||||||
			PageSize: 10,
 | 
								PageSize: 10,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		Keyword:     "test_repo",
 | 
							Keyword:     "test_repo",
 | 
				
			||||||
		Collaborate: util.OptionalBoolFalse,
 | 
							Collaborate: optional.Some(false),
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	assert.NoError(t, err)
 | 
						assert.NoError(t, err)
 | 
				
			||||||
| 
						 | 
					@ -220,7 +220,7 @@ func TestSearchRepository(t *testing.T) {
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		Keyword:     "repo_13",
 | 
							Keyword:     "repo_13",
 | 
				
			||||||
		Private:     true,
 | 
							Private:     true,
 | 
				
			||||||
		Collaborate: util.OptionalBoolFalse,
 | 
							Collaborate: optional.Some(false),
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	assert.NoError(t, err)
 | 
						assert.NoError(t, err)
 | 
				
			||||||
| 
						 | 
					@ -236,7 +236,7 @@ func TestSearchRepository(t *testing.T) {
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		Keyword:     "test_repo",
 | 
							Keyword:     "test_repo",
 | 
				
			||||||
		Private:     true,
 | 
							Private:     true,
 | 
				
			||||||
		Collaborate: util.OptionalBoolFalse,
 | 
							Collaborate: optional.Some(false),
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	assert.NoError(t, err)
 | 
						assert.NoError(t, err)
 | 
				
			||||||
| 
						 | 
					@ -257,7 +257,7 @@ func TestSearchRepository(t *testing.T) {
 | 
				
			||||||
			PageSize: 10,
 | 
								PageSize: 10,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		Keyword:            "description_14",
 | 
							Keyword:            "description_14",
 | 
				
			||||||
		Collaborate:        util.OptionalBoolFalse,
 | 
							Collaborate:        optional.Some(false),
 | 
				
			||||||
		IncludeDescription: true,
 | 
							IncludeDescription: true,
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -274,7 +274,7 @@ func TestSearchRepository(t *testing.T) {
 | 
				
			||||||
			PageSize: 10,
 | 
								PageSize: 10,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		Keyword:            "description_14",
 | 
							Keyword:            "description_14",
 | 
				
			||||||
		Collaborate:        util.OptionalBoolFalse,
 | 
							Collaborate:        optional.Some(false),
 | 
				
			||||||
		IncludeDescription: false,
 | 
							IncludeDescription: false,
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -327,30 +327,25 @@ func TestSearchRepository(t *testing.T) {
 | 
				
			||||||
						assert.False(t, repo.IsPrivate)
 | 
											assert.False(t, repo.IsPrivate)
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					if testCase.opts.Fork == util.OptionalBoolTrue && testCase.opts.Mirror == util.OptionalBoolTrue {
 | 
										if testCase.opts.Fork.Value() && testCase.opts.Mirror.Value() {
 | 
				
			||||||
						assert.True(t, repo.IsFork || repo.IsMirror)
 | 
											assert.True(t, repo.IsFork && repo.IsMirror)
 | 
				
			||||||
					} else {
 | 
										} else {
 | 
				
			||||||
						switch testCase.opts.Fork {
 | 
											if testCase.opts.Fork.Has() {
 | 
				
			||||||
						case util.OptionalBoolFalse:
 | 
												assert.Equal(t, testCase.opts.Fork.Value(), repo.IsFork)
 | 
				
			||||||
							assert.False(t, repo.IsFork)
 | 
					 | 
				
			||||||
						case util.OptionalBoolTrue:
 | 
					 | 
				
			||||||
							assert.True(t, repo.IsFork)
 | 
					 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
						switch testCase.opts.Mirror {
 | 
											if testCase.opts.Mirror.Has() {
 | 
				
			||||||
						case util.OptionalBoolFalse:
 | 
												assert.Equal(t, testCase.opts.Mirror.Value(), repo.IsMirror)
 | 
				
			||||||
							assert.False(t, repo.IsMirror)
 | 
					 | 
				
			||||||
						case util.OptionalBoolTrue:
 | 
					 | 
				
			||||||
							assert.True(t, repo.IsMirror)
 | 
					 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					if testCase.opts.OwnerID > 0 && !testCase.opts.AllPublic {
 | 
										if testCase.opts.OwnerID > 0 && !testCase.opts.AllPublic {
 | 
				
			||||||
						switch testCase.opts.Collaborate {
 | 
											if testCase.opts.Collaborate.Has() {
 | 
				
			||||||
						case util.OptionalBoolFalse:
 | 
												if testCase.opts.Collaborate.Value() {
 | 
				
			||||||
							assert.Equal(t, testCase.opts.OwnerID, repo.Owner.ID)
 | 
					 | 
				
			||||||
						case util.OptionalBoolTrue:
 | 
					 | 
				
			||||||
								assert.NotEqual(t, testCase.opts.OwnerID, repo.Owner.ID)
 | 
													assert.NotEqual(t, testCase.opts.OwnerID, repo.Owner.ID)
 | 
				
			||||||
 | 
												} else {
 | 
				
			||||||
 | 
													assert.Equal(t, testCase.opts.OwnerID, repo.Owner.ID)
 | 
				
			||||||
 | 
												}
 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -14,6 +14,7 @@ import (
 | 
				
			||||||
	"code.gitea.io/gitea/models/db"
 | 
						"code.gitea.io/gitea/models/db"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/base"
 | 
						"code.gitea.io/gitea/modules/base"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/log"
 | 
						"code.gitea.io/gitea/modules/log"
 | 
				
			||||||
 | 
						"code.gitea.io/gitea/modules/optional"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/setting"
 | 
						"code.gitea.io/gitea/modules/setting"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/util"
 | 
						"code.gitea.io/gitea/modules/util"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/validation"
 | 
						"code.gitea.io/gitea/modules/validation"
 | 
				
			||||||
| 
						 | 
					@ -425,8 +426,8 @@ type SearchEmailOptions struct {
 | 
				
			||||||
	db.ListOptions
 | 
						db.ListOptions
 | 
				
			||||||
	Keyword     string
 | 
						Keyword     string
 | 
				
			||||||
	SortType    SearchEmailOrderBy
 | 
						SortType    SearchEmailOrderBy
 | 
				
			||||||
	IsPrimary   util.OptionalBool
 | 
						IsPrimary   optional.Option[bool]
 | 
				
			||||||
	IsActivated util.OptionalBool
 | 
						IsActivated optional.Option[bool]
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// SearchEmailResult is an e-mail address found in the user or email_address table
 | 
					// SearchEmailResult is an e-mail address found in the user or email_address table
 | 
				
			||||||
| 
						 | 
					@ -453,18 +454,12 @@ func SearchEmails(ctx context.Context, opts *SearchEmailOptions) ([]*SearchEmail
 | 
				
			||||||
		))
 | 
							))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch {
 | 
						if opts.IsPrimary.Has() {
 | 
				
			||||||
	case opts.IsPrimary.IsTrue():
 | 
							cond = cond.And(builder.Eq{"email_address.is_primary": opts.IsPrimary.Value()})
 | 
				
			||||||
		cond = cond.And(builder.Eq{"email_address.is_primary": true})
 | 
					 | 
				
			||||||
	case opts.IsPrimary.IsFalse():
 | 
					 | 
				
			||||||
		cond = cond.And(builder.Eq{"email_address.is_primary": false})
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch {
 | 
						if opts.IsActivated.Has() {
 | 
				
			||||||
	case opts.IsActivated.IsTrue():
 | 
							cond = cond.And(builder.Eq{"email_address.is_activated": opts.IsActivated.Value()})
 | 
				
			||||||
		cond = cond.And(builder.Eq{"email_address.is_activated": true})
 | 
					 | 
				
			||||||
	case opts.IsActivated.IsFalse():
 | 
					 | 
				
			||||||
		cond = cond.And(builder.Eq{"email_address.is_activated": false})
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	count, err := db.GetEngine(ctx).Join("INNER", "`user`", "`user`.ID = email_address.uid").
 | 
						count, err := db.GetEngine(ctx).Join("INNER", "`user`", "`user`.ID = email_address.uid").
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -10,7 +10,7 @@ import (
 | 
				
			||||||
	"code.gitea.io/gitea/models/db"
 | 
						"code.gitea.io/gitea/models/db"
 | 
				
			||||||
	"code.gitea.io/gitea/models/unittest"
 | 
						"code.gitea.io/gitea/models/unittest"
 | 
				
			||||||
	user_model "code.gitea.io/gitea/models/user"
 | 
						user_model "code.gitea.io/gitea/models/user"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/util"
 | 
						"code.gitea.io/gitea/modules/optional"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/stretchr/testify/assert"
 | 
						"github.com/stretchr/testify/assert"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
| 
						 | 
					@ -138,14 +138,14 @@ func TestListEmails(t *testing.T) {
 | 
				
			||||||
	assert.True(t, contains(func(s *user_model.SearchEmailResult) bool { return s.UID == 27 }))
 | 
						assert.True(t, contains(func(s *user_model.SearchEmailResult) bool { return s.UID == 27 }))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Must find only primary addresses (i.e. from the `user` table)
 | 
						// Must find only primary addresses (i.e. from the `user` table)
 | 
				
			||||||
	opts = &user_model.SearchEmailOptions{IsPrimary: util.OptionalBoolTrue}
 | 
						opts = &user_model.SearchEmailOptions{IsPrimary: optional.Some(true)}
 | 
				
			||||||
	emails, _, err = user_model.SearchEmails(db.DefaultContext, opts)
 | 
						emails, _, err = user_model.SearchEmails(db.DefaultContext, opts)
 | 
				
			||||||
	assert.NoError(t, err)
 | 
						assert.NoError(t, err)
 | 
				
			||||||
	assert.True(t, contains(func(s *user_model.SearchEmailResult) bool { return s.IsPrimary }))
 | 
						assert.True(t, contains(func(s *user_model.SearchEmailResult) bool { return s.IsPrimary }))
 | 
				
			||||||
	assert.False(t, contains(func(s *user_model.SearchEmailResult) bool { return !s.IsPrimary }))
 | 
						assert.False(t, contains(func(s *user_model.SearchEmailResult) bool { return !s.IsPrimary }))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Must find only inactive addresses (i.e. not validated)
 | 
						// Must find only inactive addresses (i.e. not validated)
 | 
				
			||||||
	opts = &user_model.SearchEmailOptions{IsActivated: util.OptionalBoolFalse}
 | 
						opts = &user_model.SearchEmailOptions{IsActivated: optional.Some(false)}
 | 
				
			||||||
	emails, _, err = user_model.SearchEmails(db.DefaultContext, opts)
 | 
						emails, _, err = user_model.SearchEmails(db.DefaultContext, opts)
 | 
				
			||||||
	assert.NoError(t, err)
 | 
						assert.NoError(t, err)
 | 
				
			||||||
	assert.True(t, contains(func(s *user_model.SearchEmailResult) bool { return !s.IsActivated }))
 | 
						assert.True(t, contains(func(s *user_model.SearchEmailResult) bool { return !s.IsActivated }))
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -10,8 +10,8 @@ import (
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"code.gitea.io/gitea/models/db"
 | 
						"code.gitea.io/gitea/models/db"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/container"
 | 
						"code.gitea.io/gitea/modules/container"
 | 
				
			||||||
 | 
						"code.gitea.io/gitea/modules/optional"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/structs"
 | 
						"code.gitea.io/gitea/modules/structs"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/util"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"xorm.io/builder"
 | 
						"xorm.io/builder"
 | 
				
			||||||
	"xorm.io/xorm"
 | 
						"xorm.io/xorm"
 | 
				
			||||||
| 
						 | 
					@ -33,11 +33,11 @@ type SearchUserOptions struct {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	SupportedSortOrders container.Set[string] // if not nil, only allow to use the sort orders in this set
 | 
						SupportedSortOrders container.Set[string] // if not nil, only allow to use the sort orders in this set
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	IsActive           util.OptionalBool
 | 
						IsActive           optional.Option[bool]
 | 
				
			||||||
	IsAdmin            util.OptionalBool
 | 
						IsAdmin            optional.Option[bool]
 | 
				
			||||||
	IsRestricted       util.OptionalBool
 | 
						IsRestricted       optional.Option[bool]
 | 
				
			||||||
	IsTwoFactorEnabled util.OptionalBool
 | 
						IsTwoFactorEnabled optional.Option[bool]
 | 
				
			||||||
	IsProhibitLogin    util.OptionalBool
 | 
						IsProhibitLogin    optional.Option[bool]
 | 
				
			||||||
	IncludeReserved    bool
 | 
						IncludeReserved    bool
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ExtraParamStrings map[string]string
 | 
						ExtraParamStrings map[string]string
 | 
				
			||||||
| 
						 | 
					@ -89,24 +89,24 @@ func (opts *SearchUserOptions) toSearchQueryBase(ctx context.Context) *xorm.Sess
 | 
				
			||||||
		cond = cond.And(builder.Eq{"login_name": opts.LoginName})
 | 
							cond = cond.And(builder.Eq{"login_name": opts.LoginName})
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if !opts.IsActive.IsNone() {
 | 
						if opts.IsActive.Has() {
 | 
				
			||||||
		cond = cond.And(builder.Eq{"is_active": opts.IsActive.IsTrue()})
 | 
							cond = cond.And(builder.Eq{"is_active": opts.IsActive.Value()})
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if !opts.IsAdmin.IsNone() {
 | 
						if opts.IsAdmin.Has() {
 | 
				
			||||||
		cond = cond.And(builder.Eq{"is_admin": opts.IsAdmin.IsTrue()})
 | 
							cond = cond.And(builder.Eq{"is_admin": opts.IsAdmin.Value()})
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if !opts.IsRestricted.IsNone() {
 | 
						if opts.IsRestricted.Has() {
 | 
				
			||||||
		cond = cond.And(builder.Eq{"is_restricted": opts.IsRestricted.IsTrue()})
 | 
							cond = cond.And(builder.Eq{"is_restricted": opts.IsRestricted.Value()})
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if !opts.IsProhibitLogin.IsNone() {
 | 
						if opts.IsProhibitLogin.Has() {
 | 
				
			||||||
		cond = cond.And(builder.Eq{"prohibit_login": opts.IsProhibitLogin.IsTrue()})
 | 
							cond = cond.And(builder.Eq{"prohibit_login": opts.IsProhibitLogin.Value()})
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	e := db.GetEngine(ctx)
 | 
						e := db.GetEngine(ctx)
 | 
				
			||||||
	if opts.IsTwoFactorEnabled.IsNone() {
 | 
						if !opts.IsTwoFactorEnabled.Has() {
 | 
				
			||||||
		return e.Where(cond)
 | 
							return e.Where(cond)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -114,7 +114,7 @@ func (opts *SearchUserOptions) toSearchQueryBase(ctx context.Context) *xorm.Sess
 | 
				
			||||||
	// While using LEFT JOIN, sometimes the performance might not be good, but it won't be a problem now, such SQL is seldom executed.
 | 
						// While using LEFT JOIN, sometimes the performance might not be good, but it won't be a problem now, such SQL is seldom executed.
 | 
				
			||||||
	// There are some possible methods to refactor this SQL in future when we really need to optimize the performance (but not now):
 | 
						// There are some possible methods to refactor this SQL in future when we really need to optimize the performance (but not now):
 | 
				
			||||||
	// (1) add a column in user table (2) add a setting value in user_setting table (3) use search engines (bleve/elasticsearch)
 | 
						// (1) add a column in user table (2) add a setting value in user_setting table (3) use search engines (bleve/elasticsearch)
 | 
				
			||||||
	if opts.IsTwoFactorEnabled.IsTrue() {
 | 
						if opts.IsTwoFactorEnabled.Value() {
 | 
				
			||||||
		cond = cond.And(builder.Expr("two_factor.uid IS NOT NULL"))
 | 
							cond = cond.And(builder.Expr("two_factor.uid IS NOT NULL"))
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		cond = cond.And(builder.Expr("two_factor.uid IS NULL"))
 | 
							cond = cond.And(builder.Expr("two_factor.uid IS NULL"))
 | 
				
			||||||
| 
						 | 
					@ -131,7 +131,7 @@ func SearchUsers(ctx context.Context, opts *SearchUserOptions) (users []*User, _
 | 
				
			||||||
	defer sessCount.Close()
 | 
						defer sessCount.Close()
 | 
				
			||||||
	count, err := sessCount.Count(new(User))
 | 
						count, err := sessCount.Count(new(User))
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, 0, fmt.Errorf("Count: %w", err)
 | 
							return nil, 0, fmt.Errorf("count: %w", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if len(opts.OrderBy) == 0 {
 | 
						if len(opts.OrderBy) == 0 {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -16,10 +16,10 @@ import (
 | 
				
			||||||
	"code.gitea.io/gitea/models/unittest"
 | 
						"code.gitea.io/gitea/models/unittest"
 | 
				
			||||||
	user_model "code.gitea.io/gitea/models/user"
 | 
						user_model "code.gitea.io/gitea/models/user"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/auth/password/hash"
 | 
						"code.gitea.io/gitea/modules/auth/password/hash"
 | 
				
			||||||
 | 
						"code.gitea.io/gitea/modules/optional"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/setting"
 | 
						"code.gitea.io/gitea/modules/setting"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/structs"
 | 
						"code.gitea.io/gitea/modules/structs"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/timeutil"
 | 
						"code.gitea.io/gitea/modules/timeutil"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/util"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/stretchr/testify/assert"
 | 
						"github.com/stretchr/testify/assert"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
| 
						 | 
					@ -103,29 +103,29 @@ func TestSearchUsers(t *testing.T) {
 | 
				
			||||||
	testUserSuccess(&user_model.SearchUserOptions{OrderBy: "id ASC", ListOptions: db.ListOptions{Page: 1}},
 | 
						testUserSuccess(&user_model.SearchUserOptions{OrderBy: "id ASC", ListOptions: db.ListOptions{Page: 1}},
 | 
				
			||||||
		[]int64{1, 2, 4, 5, 8, 9, 10, 11, 12, 13, 14, 15, 16, 18, 20, 21, 24, 27, 28, 29, 30, 32, 34, 37, 38, 39, 40})
 | 
							[]int64{1, 2, 4, 5, 8, 9, 10, 11, 12, 13, 14, 15, 16, 18, 20, 21, 24, 27, 28, 29, 30, 32, 34, 37, 38, 39, 40})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	testUserSuccess(&user_model.SearchUserOptions{ListOptions: db.ListOptions{Page: 1}, IsActive: util.OptionalBoolFalse},
 | 
						testUserSuccess(&user_model.SearchUserOptions{ListOptions: db.ListOptions{Page: 1}, IsActive: optional.Some(false)},
 | 
				
			||||||
		[]int64{9})
 | 
							[]int64{9})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	testUserSuccess(&user_model.SearchUserOptions{OrderBy: "id ASC", ListOptions: db.ListOptions{Page: 1}, IsActive: util.OptionalBoolTrue},
 | 
						testUserSuccess(&user_model.SearchUserOptions{OrderBy: "id ASC", ListOptions: db.ListOptions{Page: 1}, IsActive: optional.Some(true)},
 | 
				
			||||||
		[]int64{1, 2, 4, 5, 8, 10, 11, 12, 13, 14, 15, 16, 18, 20, 21, 24, 27, 28, 29, 30, 32, 34, 37, 38, 39, 40})
 | 
							[]int64{1, 2, 4, 5, 8, 10, 11, 12, 13, 14, 15, 16, 18, 20, 21, 24, 27, 28, 29, 30, 32, 34, 37, 38, 39, 40})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	testUserSuccess(&user_model.SearchUserOptions{Keyword: "user1", OrderBy: "id ASC", ListOptions: db.ListOptions{Page: 1}, IsActive: util.OptionalBoolTrue},
 | 
						testUserSuccess(&user_model.SearchUserOptions{Keyword: "user1", OrderBy: "id ASC", ListOptions: db.ListOptions{Page: 1}, IsActive: optional.Some(true)},
 | 
				
			||||||
		[]int64{1, 10, 11, 12, 13, 14, 15, 16, 18})
 | 
							[]int64{1, 10, 11, 12, 13, 14, 15, 16, 18})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// order by name asc default
 | 
						// order by name asc default
 | 
				
			||||||
	testUserSuccess(&user_model.SearchUserOptions{Keyword: "user1", ListOptions: db.ListOptions{Page: 1}, IsActive: util.OptionalBoolTrue},
 | 
						testUserSuccess(&user_model.SearchUserOptions{Keyword: "user1", ListOptions: db.ListOptions{Page: 1}, IsActive: optional.Some(true)},
 | 
				
			||||||
		[]int64{1, 10, 11, 12, 13, 14, 15, 16, 18})
 | 
							[]int64{1, 10, 11, 12, 13, 14, 15, 16, 18})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	testUserSuccess(&user_model.SearchUserOptions{ListOptions: db.ListOptions{Page: 1}, IsAdmin: util.OptionalBoolTrue},
 | 
						testUserSuccess(&user_model.SearchUserOptions{ListOptions: db.ListOptions{Page: 1}, IsAdmin: optional.Some(true)},
 | 
				
			||||||
		[]int64{1})
 | 
							[]int64{1})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	testUserSuccess(&user_model.SearchUserOptions{ListOptions: db.ListOptions{Page: 1}, IsRestricted: util.OptionalBoolTrue},
 | 
						testUserSuccess(&user_model.SearchUserOptions{ListOptions: db.ListOptions{Page: 1}, IsRestricted: optional.Some(true)},
 | 
				
			||||||
		[]int64{29})
 | 
							[]int64{29})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	testUserSuccess(&user_model.SearchUserOptions{ListOptions: db.ListOptions{Page: 1}, IsProhibitLogin: util.OptionalBoolTrue},
 | 
						testUserSuccess(&user_model.SearchUserOptions{ListOptions: db.ListOptions{Page: 1}, IsProhibitLogin: optional.Some(true)},
 | 
				
			||||||
		[]int64{37})
 | 
							[]int64{37})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	testUserSuccess(&user_model.SearchUserOptions{ListOptions: db.ListOptions{Page: 1}, IsTwoFactorEnabled: util.OptionalBoolTrue},
 | 
						testUserSuccess(&user_model.SearchUserOptions{ListOptions: db.ListOptions{Page: 1}, IsTwoFactorEnabled: optional.Some(true)},
 | 
				
			||||||
		[]int64{24})
 | 
							[]int64{24})
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -20,10 +20,10 @@ import (
 | 
				
			||||||
	"code.gitea.io/gitea/modules/indexer/issues/internal"
 | 
						"code.gitea.io/gitea/modules/indexer/issues/internal"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/indexer/issues/meilisearch"
 | 
						"code.gitea.io/gitea/modules/indexer/issues/meilisearch"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/log"
 | 
						"code.gitea.io/gitea/modules/log"
 | 
				
			||||||
 | 
						"code.gitea.io/gitea/modules/optional"
 | 
				
			||||||
	"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"
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// IndexerMetadata is used to send data to the queue, so it contains only the ids.
 | 
					// IndexerMetadata is used to send data to the queue, so it contains only the ids.
 | 
				
			||||||
| 
						 | 
					@ -220,7 +220,7 @@ func PopulateIssueIndexer(ctx context.Context) error {
 | 
				
			||||||
			ListOptions: db_model.ListOptions{Page: page, PageSize: repo_model.RepositoryListDefaultPageSize},
 | 
								ListOptions: db_model.ListOptions{Page: page, PageSize: repo_model.RepositoryListDefaultPageSize},
 | 
				
			||||||
			OrderBy:     db_model.SearchOrderByID,
 | 
								OrderBy:     db_model.SearchOrderByID,
 | 
				
			||||||
			Private:     true,
 | 
								Private:     true,
 | 
				
			||||||
			Collaborate: util.OptionalBoolFalse,
 | 
								Collaborate: optional.Some(false),
 | 
				
			||||||
		})
 | 
							})
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			log.Error("SearchRepositoryByName: %v", err)
 | 
								log.Error("SearchRepositoryByName: %v", err)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -27,6 +27,16 @@ func TestOption(t *testing.T) {
 | 
				
			||||||
	assert.Equal(t, int(1), some.Value())
 | 
						assert.Equal(t, int(1), some.Value())
 | 
				
			||||||
	assert.Equal(t, int(1), some.ValueOrDefault(2))
 | 
						assert.Equal(t, int(1), some.ValueOrDefault(2))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						noneBool := optional.None[bool]()
 | 
				
			||||||
 | 
						assert.False(t, noneBool.Has())
 | 
				
			||||||
 | 
						assert.False(t, noneBool.Value())
 | 
				
			||||||
 | 
						assert.True(t, noneBool.ValueOrDefault(true))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						someBool := optional.Some(true)
 | 
				
			||||||
 | 
						assert.True(t, someBool.Has())
 | 
				
			||||||
 | 
						assert.True(t, someBool.Value())
 | 
				
			||||||
 | 
						assert.True(t, someBool.ValueOrDefault(false))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var ptr *int
 | 
						var ptr *int
 | 
				
			||||||
	assert.False(t, optional.FromPtr(ptr).Has())
 | 
						assert.False(t, optional.FromPtr(ptr).Has())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -68,13 +68,13 @@ func OptionalBoolOf(b bool) OptionalBool {
 | 
				
			||||||
	return OptionalBoolFalse
 | 
						return OptionalBoolFalse
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// OptionalBoolParse get the corresponding OptionalBool of a string using strconv.ParseBool
 | 
					// OptionalBoolParse get the corresponding optional.Option[bool] of a string using strconv.ParseBool
 | 
				
			||||||
func OptionalBoolParse(s string) OptionalBool {
 | 
					func OptionalBoolParse(s string) optional.Option[bool] {
 | 
				
			||||||
	b, e := strconv.ParseBool(s)
 | 
						v, e := strconv.ParseBool(s)
 | 
				
			||||||
	if e != nil {
 | 
						if e != nil {
 | 
				
			||||||
		return OptionalBoolNone
 | 
							return optional.None[bool]()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return OptionalBoolOf(b)
 | 
						return optional.Some(v)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// IsEmptyString checks if the provided string is empty
 | 
					// IsEmptyString checks if the provided string is empty
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,6 +8,8 @@ import (
 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
	"testing"
 | 
						"testing"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"code.gitea.io/gitea/modules/optional"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/stretchr/testify/assert"
 | 
						"github.com/stretchr/testify/assert"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -173,17 +175,17 @@ func Test_RandomBytes(t *testing.T) {
 | 
				
			||||||
	assert.NotEqual(t, bytes3, bytes4)
 | 
						assert.NotEqual(t, bytes3, bytes4)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func Test_OptionalBool(t *testing.T) {
 | 
					func TestOptionalBoolParse(t *testing.T) {
 | 
				
			||||||
	assert.Equal(t, OptionalBoolNone, OptionalBoolParse(""))
 | 
						assert.Equal(t, optional.None[bool](), OptionalBoolParse(""))
 | 
				
			||||||
	assert.Equal(t, OptionalBoolNone, OptionalBoolParse("x"))
 | 
						assert.Equal(t, optional.None[bool](), OptionalBoolParse("x"))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	assert.Equal(t, OptionalBoolFalse, OptionalBoolParse("0"))
 | 
						assert.Equal(t, optional.Some(false), OptionalBoolParse("0"))
 | 
				
			||||||
	assert.Equal(t, OptionalBoolFalse, OptionalBoolParse("f"))
 | 
						assert.Equal(t, optional.Some(false), OptionalBoolParse("f"))
 | 
				
			||||||
	assert.Equal(t, OptionalBoolFalse, OptionalBoolParse("False"))
 | 
						assert.Equal(t, optional.Some(false), OptionalBoolParse("False"))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	assert.Equal(t, OptionalBoolTrue, OptionalBoolParse("1"))
 | 
						assert.Equal(t, optional.Some(true), OptionalBoolParse("1"))
 | 
				
			||||||
	assert.Equal(t, OptionalBoolTrue, OptionalBoolParse("t"))
 | 
						assert.Equal(t, optional.Some(true), OptionalBoolParse("t"))
 | 
				
			||||||
	assert.Equal(t, OptionalBoolTrue, OptionalBoolParse("True"))
 | 
						assert.Equal(t, optional.Some(true), OptionalBoolParse("True"))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Test case for any function which accepts and returns a single string.
 | 
					// Test case for any function which accepts and returns a single string.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -20,6 +20,7 @@ import (
 | 
				
			||||||
	"code.gitea.io/gitea/models/unit"
 | 
						"code.gitea.io/gitea/models/unit"
 | 
				
			||||||
	user_model "code.gitea.io/gitea/models/user"
 | 
						user_model "code.gitea.io/gitea/models/user"
 | 
				
			||||||
	issue_indexer "code.gitea.io/gitea/modules/indexer/issues"
 | 
						issue_indexer "code.gitea.io/gitea/modules/indexer/issues"
 | 
				
			||||||
 | 
						"code.gitea.io/gitea/modules/optional"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/setting"
 | 
						"code.gitea.io/gitea/modules/setting"
 | 
				
			||||||
	api "code.gitea.io/gitea/modules/structs"
 | 
						api "code.gitea.io/gitea/modules/structs"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/timeutil"
 | 
						"code.gitea.io/gitea/modules/timeutil"
 | 
				
			||||||
| 
						 | 
					@ -143,7 +144,7 @@ func SearchIssues(ctx *context.APIContext) {
 | 
				
			||||||
			Private:     false,
 | 
								Private:     false,
 | 
				
			||||||
			AllPublic:   true,
 | 
								AllPublic:   true,
 | 
				
			||||||
			TopicOnly:   false,
 | 
								TopicOnly:   false,
 | 
				
			||||||
			Collaborate: util.OptionalBoolNone,
 | 
								Collaborate: optional.None[bool](),
 | 
				
			||||||
			// This needs to be a column that is not nil in fixtures or
 | 
								// This needs to be a column that is not nil in fixtures or
 | 
				
			||||||
			// MySQL will return different results when sorting by null in some cases
 | 
								// MySQL will return different results when sorting by null in some cases
 | 
				
			||||||
			OrderBy: db.SearchOrderByAlphabetically,
 | 
								OrderBy: db.SearchOrderByAlphabetically,
 | 
				
			||||||
| 
						 | 
					@ -166,7 +167,7 @@ func SearchIssues(ctx *context.APIContext) {
 | 
				
			||||||
			opts.OwnerID = owner.ID
 | 
								opts.OwnerID = owner.ID
 | 
				
			||||||
			opts.AllLimited = false
 | 
								opts.AllLimited = false
 | 
				
			||||||
			opts.AllPublic = false
 | 
								opts.AllPublic = false
 | 
				
			||||||
			opts.Collaborate = util.OptionalBoolFalse
 | 
								opts.Collaborate = optional.Some(false)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if ctx.FormString("team") != "" {
 | 
							if ctx.FormString("team") != "" {
 | 
				
			||||||
			if ctx.FormString("owner") == "" {
 | 
								if ctx.FormString("owner") == "" {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -23,10 +23,10 @@ import (
 | 
				
			||||||
	"code.gitea.io/gitea/modules/gitrepo"
 | 
						"code.gitea.io/gitea/modules/gitrepo"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/label"
 | 
						"code.gitea.io/gitea/modules/label"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/log"
 | 
						"code.gitea.io/gitea/modules/log"
 | 
				
			||||||
 | 
						"code.gitea.io/gitea/modules/optional"
 | 
				
			||||||
	repo_module "code.gitea.io/gitea/modules/repository"
 | 
						repo_module "code.gitea.io/gitea/modules/repository"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/setting"
 | 
						"code.gitea.io/gitea/modules/setting"
 | 
				
			||||||
	api "code.gitea.io/gitea/modules/structs"
 | 
						api "code.gitea.io/gitea/modules/structs"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/util"
 | 
					 | 
				
			||||||
	"code.gitea.io/gitea/modules/validation"
 | 
						"code.gitea.io/gitea/modules/validation"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/web"
 | 
						"code.gitea.io/gitea/modules/web"
 | 
				
			||||||
	"code.gitea.io/gitea/routers/api/v1/utils"
 | 
						"code.gitea.io/gitea/routers/api/v1/utils"
 | 
				
			||||||
| 
						 | 
					@ -135,33 +135,33 @@ func Search(ctx *context.APIContext) {
 | 
				
			||||||
		PriorityOwnerID:    ctx.FormInt64("priority_owner_id"),
 | 
							PriorityOwnerID:    ctx.FormInt64("priority_owner_id"),
 | 
				
			||||||
		TeamID:             ctx.FormInt64("team_id"),
 | 
							TeamID:             ctx.FormInt64("team_id"),
 | 
				
			||||||
		TopicOnly:          ctx.FormBool("topic"),
 | 
							TopicOnly:          ctx.FormBool("topic"),
 | 
				
			||||||
		Collaborate:        util.OptionalBoolNone,
 | 
							Collaborate:        optional.None[bool](),
 | 
				
			||||||
		Private:            ctx.IsSigned && (ctx.FormString("private") == "" || ctx.FormBool("private")),
 | 
							Private:            ctx.IsSigned && (ctx.FormString("private") == "" || ctx.FormBool("private")),
 | 
				
			||||||
		Template:           util.OptionalBoolNone,
 | 
							Template:           optional.None[bool](),
 | 
				
			||||||
		StarredByID:        ctx.FormInt64("starredBy"),
 | 
							StarredByID:        ctx.FormInt64("starredBy"),
 | 
				
			||||||
		IncludeDescription: ctx.FormBool("includeDesc"),
 | 
							IncludeDescription: ctx.FormBool("includeDesc"),
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ctx.FormString("template") != "" {
 | 
						if ctx.FormString("template") != "" {
 | 
				
			||||||
		opts.Template = util.OptionalBoolOf(ctx.FormBool("template"))
 | 
							opts.Template = optional.Some(ctx.FormBool("template"))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ctx.FormBool("exclusive") {
 | 
						if ctx.FormBool("exclusive") {
 | 
				
			||||||
		opts.Collaborate = util.OptionalBoolFalse
 | 
							opts.Collaborate = optional.Some(false)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	mode := ctx.FormString("mode")
 | 
						mode := ctx.FormString("mode")
 | 
				
			||||||
	switch mode {
 | 
						switch mode {
 | 
				
			||||||
	case "source":
 | 
						case "source":
 | 
				
			||||||
		opts.Fork = util.OptionalBoolFalse
 | 
							opts.Fork = optional.Some(false)
 | 
				
			||||||
		opts.Mirror = util.OptionalBoolFalse
 | 
							opts.Mirror = optional.Some(false)
 | 
				
			||||||
	case "fork":
 | 
						case "fork":
 | 
				
			||||||
		opts.Fork = util.OptionalBoolTrue
 | 
							opts.Fork = optional.Some(true)
 | 
				
			||||||
	case "mirror":
 | 
						case "mirror":
 | 
				
			||||||
		opts.Mirror = util.OptionalBoolTrue
 | 
							opts.Mirror = optional.Some(true)
 | 
				
			||||||
	case "collaborative":
 | 
						case "collaborative":
 | 
				
			||||||
		opts.Mirror = util.OptionalBoolFalse
 | 
							opts.Mirror = optional.Some(false)
 | 
				
			||||||
		opts.Collaborate = util.OptionalBoolTrue
 | 
							opts.Collaborate = optional.Some(true)
 | 
				
			||||||
	case "":
 | 
						case "":
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		ctx.Error(http.StatusUnprocessableEntity, "", fmt.Errorf("Invalid search mode: \"%s\"", mode))
 | 
							ctx.Error(http.StatusUnprocessableEntity, "", fmt.Errorf("Invalid search mode: \"%s\"", mode))
 | 
				
			||||||
| 
						 | 
					@ -169,11 +169,11 @@ func Search(ctx *context.APIContext) {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ctx.FormString("archived") != "" {
 | 
						if ctx.FormString("archived") != "" {
 | 
				
			||||||
		opts.Archived = util.OptionalBoolOf(ctx.FormBool("archived"))
 | 
							opts.Archived = optional.Some(ctx.FormBool("archived"))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ctx.FormString("is_private") != "" {
 | 
						if ctx.FormString("is_private") != "" {
 | 
				
			||||||
		opts.IsPrivate = util.OptionalBoolOf(ctx.FormBool("is_private"))
 | 
							opts.IsPrivate = optional.Some(ctx.FormBool("is_private"))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sortMode := ctx.FormString("sort")
 | 
						sortMode := ctx.FormString("sort")
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -12,8 +12,8 @@ import (
 | 
				
			||||||
	user_model "code.gitea.io/gitea/models/user"
 | 
						user_model "code.gitea.io/gitea/models/user"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/base"
 | 
						"code.gitea.io/gitea/modules/base"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/log"
 | 
						"code.gitea.io/gitea/modules/log"
 | 
				
			||||||
 | 
						"code.gitea.io/gitea/modules/optional"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/setting"
 | 
						"code.gitea.io/gitea/modules/setting"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/util"
 | 
					 | 
				
			||||||
	"code.gitea.io/gitea/services/context"
 | 
						"code.gitea.io/gitea/services/context"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -68,10 +68,10 @@ func Emails(ctx *context.Context) {
 | 
				
			||||||
	opts.Keyword = ctx.FormTrim("q")
 | 
						opts.Keyword = ctx.FormTrim("q")
 | 
				
			||||||
	opts.SortType = orderBy
 | 
						opts.SortType = orderBy
 | 
				
			||||||
	if len(ctx.FormString("is_activated")) != 0 {
 | 
						if len(ctx.FormString("is_activated")) != 0 {
 | 
				
			||||||
		opts.IsActivated = util.OptionalBoolOf(ctx.FormBool("activated"))
 | 
							opts.IsActivated = optional.Some(ctx.FormBool("activated"))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if len(ctx.FormString("is_primary")) != 0 {
 | 
						if len(ctx.FormString("is_primary")) != 0 {
 | 
				
			||||||
		opts.IsPrimary = util.OptionalBoolOf(ctx.FormBool("primary"))
 | 
							opts.IsPrimary = optional.Some(ctx.FormBool("primary"))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if len(opts.Keyword) == 0 || isKeywordValid(opts.Keyword) {
 | 
						if len(opts.Keyword) == 0 || isKeywordValid(opts.Keyword) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -276,7 +276,7 @@ func ViewUser(ctx *context.Context) {
 | 
				
			||||||
		OwnerID:     u.ID,
 | 
							OwnerID:     u.ID,
 | 
				
			||||||
		OrderBy:     db.SearchOrderByAlphabetically,
 | 
							OrderBy:     db.SearchOrderByAlphabetically,
 | 
				
			||||||
		Private:     true,
 | 
							Private:     true,
 | 
				
			||||||
		Collaborate: util.OptionalBoolFalse,
 | 
							Collaborate: optional.Some(false),
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		ctx.ServerError("SearchRepository", err)
 | 
							ctx.ServerError("SearchRepository", err)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -12,10 +12,10 @@ import (
 | 
				
			||||||
	"code.gitea.io/gitea/modules/base"
 | 
						"code.gitea.io/gitea/modules/base"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/container"
 | 
						"code.gitea.io/gitea/modules/container"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/log"
 | 
						"code.gitea.io/gitea/modules/log"
 | 
				
			||||||
 | 
						"code.gitea.io/gitea/modules/optional"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/setting"
 | 
						"code.gitea.io/gitea/modules/setting"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/sitemap"
 | 
						"code.gitea.io/gitea/modules/sitemap"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/structs"
 | 
						"code.gitea.io/gitea/modules/structs"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/util"
 | 
					 | 
				
			||||||
	"code.gitea.io/gitea/services/context"
 | 
						"code.gitea.io/gitea/services/context"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -155,7 +155,7 @@ func Users(ctx *context.Context) {
 | 
				
			||||||
		Actor:       ctx.Doer,
 | 
							Actor:       ctx.Doer,
 | 
				
			||||||
		Type:        user_model.UserTypeIndividual,
 | 
							Type:        user_model.UserTypeIndividual,
 | 
				
			||||||
		ListOptions: db.ListOptions{PageSize: setting.UI.ExplorePagingNum},
 | 
							ListOptions: db.ListOptions{PageSize: setting.UI.ExplorePagingNum},
 | 
				
			||||||
		IsActive:    util.OptionalBoolTrue,
 | 
							IsActive:    optional.Some(true),
 | 
				
			||||||
		Visible:     []structs.VisibleType{structs.VisibleTypePublic, structs.VisibleTypeLimited, structs.VisibleTypePrivate},
 | 
							Visible:     []structs.VisibleType{structs.VisibleTypePublic, structs.VisibleTypeLimited, structs.VisibleTypePrivate},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		SupportedSortOrders: supportedSortOrders,
 | 
							SupportedSortOrders: supportedSortOrders,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -13,10 +13,10 @@ import (
 | 
				
			||||||
	user_model "code.gitea.io/gitea/models/user"
 | 
						user_model "code.gitea.io/gitea/models/user"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/base"
 | 
						"code.gitea.io/gitea/modules/base"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/log"
 | 
						"code.gitea.io/gitea/modules/log"
 | 
				
			||||||
 | 
						"code.gitea.io/gitea/modules/optional"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/setting"
 | 
						"code.gitea.io/gitea/modules/setting"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/sitemap"
 | 
						"code.gitea.io/gitea/modules/sitemap"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/structs"
 | 
						"code.gitea.io/gitea/modules/structs"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/util"
 | 
					 | 
				
			||||||
	"code.gitea.io/gitea/modules/web/middleware"
 | 
						"code.gitea.io/gitea/modules/web/middleware"
 | 
				
			||||||
	"code.gitea.io/gitea/routers/web/auth"
 | 
						"code.gitea.io/gitea/routers/web/auth"
 | 
				
			||||||
	"code.gitea.io/gitea/routers/web/user"
 | 
						"code.gitea.io/gitea/routers/web/user"
 | 
				
			||||||
| 
						 | 
					@ -71,7 +71,7 @@ func HomeSitemap(ctx *context.Context) {
 | 
				
			||||||
		_, cnt, err := user_model.SearchUsers(ctx, &user_model.SearchUserOptions{
 | 
							_, cnt, err := user_model.SearchUsers(ctx, &user_model.SearchUserOptions{
 | 
				
			||||||
			Type:        user_model.UserTypeIndividual,
 | 
								Type:        user_model.UserTypeIndividual,
 | 
				
			||||||
			ListOptions: db.ListOptions{PageSize: 1},
 | 
								ListOptions: db.ListOptions{PageSize: 1},
 | 
				
			||||||
			IsActive:    util.OptionalBoolTrue,
 | 
								IsActive:    optional.Some(true),
 | 
				
			||||||
			Visible:     []structs.VisibleType{structs.VisibleTypePublic},
 | 
								Visible:     []structs.VisibleType{structs.VisibleTypePublic},
 | 
				
			||||||
		})
 | 
							})
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -38,6 +38,7 @@ import (
 | 
				
			||||||
	"code.gitea.io/gitea/modules/log"
 | 
						"code.gitea.io/gitea/modules/log"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/markup"
 | 
						"code.gitea.io/gitea/modules/markup"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/markup/markdown"
 | 
						"code.gitea.io/gitea/modules/markup/markdown"
 | 
				
			||||||
 | 
						"code.gitea.io/gitea/modules/optional"
 | 
				
			||||||
	repo_module "code.gitea.io/gitea/modules/repository"
 | 
						repo_module "code.gitea.io/gitea/modules/repository"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/setting"
 | 
						"code.gitea.io/gitea/modules/setting"
 | 
				
			||||||
	api "code.gitea.io/gitea/modules/structs"
 | 
						api "code.gitea.io/gitea/modules/structs"
 | 
				
			||||||
| 
						 | 
					@ -2529,7 +2530,7 @@ func SearchIssues(ctx *context.Context) {
 | 
				
			||||||
			Private:     false,
 | 
								Private:     false,
 | 
				
			||||||
			AllPublic:   true,
 | 
								AllPublic:   true,
 | 
				
			||||||
			TopicOnly:   false,
 | 
								TopicOnly:   false,
 | 
				
			||||||
			Collaborate: util.OptionalBoolNone,
 | 
								Collaborate: optional.None[bool](),
 | 
				
			||||||
			// This needs to be a column that is not nil in fixtures or
 | 
								// This needs to be a column that is not nil in fixtures or
 | 
				
			||||||
			// MySQL will return different results when sorting by null in some cases
 | 
								// MySQL will return different results when sorting by null in some cases
 | 
				
			||||||
			OrderBy: db.SearchOrderByAlphabetically,
 | 
								OrderBy: db.SearchOrderByAlphabetically,
 | 
				
			||||||
| 
						 | 
					@ -2553,7 +2554,7 @@ func SearchIssues(ctx *context.Context) {
 | 
				
			||||||
			opts.OwnerID = owner.ID
 | 
								opts.OwnerID = owner.ID
 | 
				
			||||||
			opts.AllLimited = false
 | 
								opts.AllLimited = false
 | 
				
			||||||
			opts.AllPublic = false
 | 
								opts.AllPublic = false
 | 
				
			||||||
			opts.Collaborate = util.OptionalBoolFalse
 | 
								opts.Collaborate = optional.Some(false)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if ctx.FormString("team") != "" {
 | 
							if ctx.FormString("team") != "" {
 | 
				
			||||||
			if ctx.FormString("owner") == "" {
 | 
								if ctx.FormString("owner") == "" {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -553,33 +553,33 @@ func SearchRepo(ctx *context.Context) {
 | 
				
			||||||
		PriorityOwnerID:    ctx.FormInt64("priority_owner_id"),
 | 
							PriorityOwnerID:    ctx.FormInt64("priority_owner_id"),
 | 
				
			||||||
		TeamID:             ctx.FormInt64("team_id"),
 | 
							TeamID:             ctx.FormInt64("team_id"),
 | 
				
			||||||
		TopicOnly:          ctx.FormBool("topic"),
 | 
							TopicOnly:          ctx.FormBool("topic"),
 | 
				
			||||||
		Collaborate:        util.OptionalBoolNone,
 | 
							Collaborate:        optional.None[bool](),
 | 
				
			||||||
		Private:            ctx.IsSigned && (ctx.FormString("private") == "" || ctx.FormBool("private")),
 | 
							Private:            ctx.IsSigned && (ctx.FormString("private") == "" || ctx.FormBool("private")),
 | 
				
			||||||
		Template:           util.OptionalBoolNone,
 | 
							Template:           optional.None[bool](),
 | 
				
			||||||
		StarredByID:        ctx.FormInt64("starredBy"),
 | 
							StarredByID:        ctx.FormInt64("starredBy"),
 | 
				
			||||||
		IncludeDescription: ctx.FormBool("includeDesc"),
 | 
							IncludeDescription: ctx.FormBool("includeDesc"),
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ctx.FormString("template") != "" {
 | 
						if ctx.FormString("template") != "" {
 | 
				
			||||||
		opts.Template = util.OptionalBoolOf(ctx.FormBool("template"))
 | 
							opts.Template = optional.Some(ctx.FormBool("template"))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ctx.FormBool("exclusive") {
 | 
						if ctx.FormBool("exclusive") {
 | 
				
			||||||
		opts.Collaborate = util.OptionalBoolFalse
 | 
							opts.Collaborate = optional.Some(false)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	mode := ctx.FormString("mode")
 | 
						mode := ctx.FormString("mode")
 | 
				
			||||||
	switch mode {
 | 
						switch mode {
 | 
				
			||||||
	case "source":
 | 
						case "source":
 | 
				
			||||||
		opts.Fork = util.OptionalBoolFalse
 | 
							opts.Fork = optional.Some(false)
 | 
				
			||||||
		opts.Mirror = util.OptionalBoolFalse
 | 
							opts.Mirror = optional.Some(false)
 | 
				
			||||||
	case "fork":
 | 
						case "fork":
 | 
				
			||||||
		opts.Fork = util.OptionalBoolTrue
 | 
							opts.Fork = optional.Some(true)
 | 
				
			||||||
	case "mirror":
 | 
						case "mirror":
 | 
				
			||||||
		opts.Mirror = util.OptionalBoolTrue
 | 
							opts.Mirror = optional.Some(true)
 | 
				
			||||||
	case "collaborative":
 | 
						case "collaborative":
 | 
				
			||||||
		opts.Mirror = util.OptionalBoolFalse
 | 
							opts.Mirror = optional.Some(false)
 | 
				
			||||||
		opts.Collaborate = util.OptionalBoolTrue
 | 
							opts.Collaborate = optional.Some(true)
 | 
				
			||||||
	case "":
 | 
						case "":
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		ctx.Error(http.StatusUnprocessableEntity, fmt.Sprintf("Invalid search mode: \"%s\"", mode))
 | 
							ctx.Error(http.StatusUnprocessableEntity, fmt.Sprintf("Invalid search mode: \"%s\"", mode))
 | 
				
			||||||
| 
						 | 
					@ -587,11 +587,11 @@ func SearchRepo(ctx *context.Context) {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ctx.FormString("archived") != "" {
 | 
						if ctx.FormString("archived") != "" {
 | 
				
			||||||
		opts.Archived = util.OptionalBoolOf(ctx.FormBool("archived"))
 | 
							opts.Archived = optional.Some(ctx.FormBool("archived"))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ctx.FormString("is_private") != "" {
 | 
						if ctx.FormString("is_private") != "" {
 | 
				
			||||||
		opts.IsPrivate = util.OptionalBoolOf(ctx.FormBool("is_private"))
 | 
							opts.IsPrivate = optional.Some(ctx.FormBool("is_private"))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sortMode := ctx.FormString("sort")
 | 
						sortMode := ctx.FormString("sort")
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -16,6 +16,7 @@ import (
 | 
				
			||||||
	"code.gitea.io/gitea/modules/git"
 | 
						"code.gitea.io/gitea/modules/git"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/gitrepo"
 | 
						"code.gitea.io/gitea/modules/gitrepo"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/log"
 | 
						"code.gitea.io/gitea/modules/log"
 | 
				
			||||||
 | 
						"code.gitea.io/gitea/modules/optional"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/setting"
 | 
						"code.gitea.io/gitea/modules/setting"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/util"
 | 
						"code.gitea.io/gitea/modules/util"
 | 
				
			||||||
	"code.gitea.io/gitea/services/context"
 | 
						"code.gitea.io/gitea/services/context"
 | 
				
			||||||
| 
						 | 
					@ -115,7 +116,7 @@ func LoadHeaderCount(ctx *context.Context) error {
 | 
				
			||||||
		Actor:              ctx.Doer,
 | 
							Actor:              ctx.Doer,
 | 
				
			||||||
		OwnerID:            ctx.ContextUser.ID,
 | 
							OwnerID:            ctx.ContextUser.ID,
 | 
				
			||||||
		Private:            ctx.IsSigned,
 | 
							Private:            ctx.IsSigned,
 | 
				
			||||||
		Collaborate:        util.OptionalBoolFalse,
 | 
							Collaborate:        optional.Some(false),
 | 
				
			||||||
		IncludeDescription: setting.UI.SearchRepoDescription,
 | 
							IncludeDescription: setting.UI.SearchRepoDescription,
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -28,6 +28,7 @@ import (
 | 
				
			||||||
	"code.gitea.io/gitea/modules/log"
 | 
						"code.gitea.io/gitea/modules/log"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/markup"
 | 
						"code.gitea.io/gitea/modules/markup"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/markup/markdown"
 | 
						"code.gitea.io/gitea/modules/markup/markdown"
 | 
				
			||||||
 | 
						"code.gitea.io/gitea/modules/optional"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/setting"
 | 
						"code.gitea.io/gitea/modules/setting"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/util"
 | 
						"code.gitea.io/gitea/modules/util"
 | 
				
			||||||
	"code.gitea.io/gitea/routers/web/feed"
 | 
						"code.gitea.io/gitea/routers/web/feed"
 | 
				
			||||||
| 
						 | 
					@ -161,8 +162,8 @@ func Milestones(ctx *context.Context) {
 | 
				
			||||||
		Private:       true,
 | 
							Private:       true,
 | 
				
			||||||
		AllPublic:     false, // Include also all public repositories of users and public organisations
 | 
							AllPublic:     false, // Include also all public repositories of users and public organisations
 | 
				
			||||||
		AllLimited:    false, // Include also all public repositories of limited organisations
 | 
							AllLimited:    false, // Include also all public repositories of limited organisations
 | 
				
			||||||
		Archived:      util.OptionalBoolFalse,
 | 
							Archived:      optional.Some(false),
 | 
				
			||||||
		HasMilestones: util.OptionalBoolTrue, // Just needs display repos has milestones
 | 
							HasMilestones: optional.Some(true), // Just needs display repos has milestones
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ctxUser.IsOrganization() && ctx.Org.Team != nil {
 | 
						if ctxUser.IsOrganization() && ctx.Org.Team != nil {
 | 
				
			||||||
| 
						 | 
					@ -465,9 +466,9 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) {
 | 
				
			||||||
		Private:     true,
 | 
							Private:     true,
 | 
				
			||||||
		AllPublic:   false,
 | 
							AllPublic:   false,
 | 
				
			||||||
		AllLimited:  false,
 | 
							AllLimited:  false,
 | 
				
			||||||
		Collaborate: util.OptionalBoolNone,
 | 
							Collaborate: optional.None[bool](),
 | 
				
			||||||
		UnitType:    unitType,
 | 
							UnitType:    unitType,
 | 
				
			||||||
		Archived:    util.OptionalBoolFalse,
 | 
							Archived:    optional.Some(false),
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if team != nil {
 | 
						if team != nil {
 | 
				
			||||||
		repoOpts.TeamID = team.ID
 | 
							repoOpts.TeamID = team.ID
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -17,6 +17,7 @@ import (
 | 
				
			||||||
	repo_model "code.gitea.io/gitea/models/repo"
 | 
						repo_model "code.gitea.io/gitea/models/repo"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/base"
 | 
						"code.gitea.io/gitea/modules/base"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/log"
 | 
						"code.gitea.io/gitea/modules/log"
 | 
				
			||||||
 | 
						"code.gitea.io/gitea/modules/optional"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/setting"
 | 
						"code.gitea.io/gitea/modules/setting"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/structs"
 | 
						"code.gitea.io/gitea/modules/structs"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/util"
 | 
						"code.gitea.io/gitea/modules/util"
 | 
				
			||||||
| 
						 | 
					@ -399,7 +400,7 @@ func NotificationWatching(ctx *context.Context) {
 | 
				
			||||||
		OrderBy:            orderBy,
 | 
							OrderBy:            orderBy,
 | 
				
			||||||
		Private:            ctx.IsSigned,
 | 
							Private:            ctx.IsSigned,
 | 
				
			||||||
		WatchedByID:        ctx.Doer.ID,
 | 
							WatchedByID:        ctx.Doer.ID,
 | 
				
			||||||
		Collaborate:        util.OptionalBoolFalse,
 | 
							Collaborate:        optional.Some(false),
 | 
				
			||||||
		TopicOnly:          ctx.FormBool("topic"),
 | 
							TopicOnly:          ctx.FormBool("topic"),
 | 
				
			||||||
		IncludeDescription: setting.UI.SearchRepoDescription,
 | 
							IncludeDescription: setting.UI.SearchRepoDescription,
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -20,6 +20,7 @@ import (
 | 
				
			||||||
	"code.gitea.io/gitea/modules/log"
 | 
						"code.gitea.io/gitea/modules/log"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/markup"
 | 
						"code.gitea.io/gitea/modules/markup"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/markup/markdown"
 | 
						"code.gitea.io/gitea/modules/markup/markdown"
 | 
				
			||||||
 | 
						"code.gitea.io/gitea/modules/optional"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/setting"
 | 
						"code.gitea.io/gitea/modules/setting"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/util"
 | 
						"code.gitea.io/gitea/modules/util"
 | 
				
			||||||
	"code.gitea.io/gitea/routers/web/feed"
 | 
						"code.gitea.io/gitea/routers/web/feed"
 | 
				
			||||||
| 
						 | 
					@ -205,7 +206,7 @@ func prepareUserProfileTabData(ctx *context.Context, showPrivate bool, profileDb
 | 
				
			||||||
			OrderBy:            orderBy,
 | 
								OrderBy:            orderBy,
 | 
				
			||||||
			Private:            ctx.IsSigned,
 | 
								Private:            ctx.IsSigned,
 | 
				
			||||||
			StarredByID:        ctx.ContextUser.ID,
 | 
								StarredByID:        ctx.ContextUser.ID,
 | 
				
			||||||
			Collaborate:        util.OptionalBoolFalse,
 | 
								Collaborate:        optional.Some(false),
 | 
				
			||||||
			TopicOnly:          topicOnly,
 | 
								TopicOnly:          topicOnly,
 | 
				
			||||||
			Language:           language,
 | 
								Language:           language,
 | 
				
			||||||
			IncludeDescription: setting.UI.SearchRepoDescription,
 | 
								IncludeDescription: setting.UI.SearchRepoDescription,
 | 
				
			||||||
| 
						 | 
					@ -227,7 +228,7 @@ func prepareUserProfileTabData(ctx *context.Context, showPrivate bool, profileDb
 | 
				
			||||||
			OrderBy:            orderBy,
 | 
								OrderBy:            orderBy,
 | 
				
			||||||
			Private:            ctx.IsSigned,
 | 
								Private:            ctx.IsSigned,
 | 
				
			||||||
			WatchedByID:        ctx.ContextUser.ID,
 | 
								WatchedByID:        ctx.ContextUser.ID,
 | 
				
			||||||
			Collaborate:        util.OptionalBoolFalse,
 | 
								Collaborate:        optional.Some(false),
 | 
				
			||||||
			TopicOnly:          topicOnly,
 | 
								TopicOnly:          topicOnly,
 | 
				
			||||||
			Language:           language,
 | 
								Language:           language,
 | 
				
			||||||
			IncludeDescription: setting.UI.SearchRepoDescription,
 | 
								IncludeDescription: setting.UI.SearchRepoDescription,
 | 
				
			||||||
| 
						 | 
					@ -272,7 +273,7 @@ func prepareUserProfileTabData(ctx *context.Context, showPrivate bool, profileDb
 | 
				
			||||||
			OwnerID:            ctx.ContextUser.ID,
 | 
								OwnerID:            ctx.ContextUser.ID,
 | 
				
			||||||
			OrderBy:            orderBy,
 | 
								OrderBy:            orderBy,
 | 
				
			||||||
			Private:            ctx.IsSigned,
 | 
								Private:            ctx.IsSigned,
 | 
				
			||||||
			Collaborate:        util.OptionalBoolFalse,
 | 
								Collaborate:        optional.Some(false),
 | 
				
			||||||
			TopicOnly:          topicOnly,
 | 
								TopicOnly:          topicOnly,
 | 
				
			||||||
			Language:           language,
 | 
								Language:           language,
 | 
				
			||||||
			IncludeDescription: setting.UI.SearchRepoDescription,
 | 
								IncludeDescription: setting.UI.SearchRepoDescription,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,7 +8,6 @@ import (
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"code.gitea.io/gitea/models/db"
 | 
						"code.gitea.io/gitea/models/db"
 | 
				
			||||||
	user_model "code.gitea.io/gitea/models/user"
 | 
						user_model "code.gitea.io/gitea/models/user"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/util"
 | 
					 | 
				
			||||||
	"code.gitea.io/gitea/services/context"
 | 
						"code.gitea.io/gitea/services/context"
 | 
				
			||||||
	"code.gitea.io/gitea/services/convert"
 | 
						"code.gitea.io/gitea/services/convert"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
| 
						 | 
					@ -25,7 +24,7 @@ func Search(ctx *context.Context) {
 | 
				
			||||||
		Keyword:     ctx.FormTrim("q"),
 | 
							Keyword:     ctx.FormTrim("q"),
 | 
				
			||||||
		UID:         ctx.FormInt64("uid"),
 | 
							UID:         ctx.FormInt64("uid"),
 | 
				
			||||||
		Type:        user_model.UserTypeIndividual,
 | 
							Type:        user_model.UserTypeIndividual,
 | 
				
			||||||
		IsActive:    util.OptionalBoolFromGeneric(ctx.FormOptionalBool("active")),
 | 
							IsActive:    ctx.FormOptionalBool("active"),
 | 
				
			||||||
		ListOptions: listOptions,
 | 
							ListOptions: listOptions,
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue