forked from gitea/gitea
		
	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>
This commit is contained in:
		
							parent
							
								
									c7dcb58b1d
								
							
						
					
					
						commit
						f6656181e4
					
				| @ -13,6 +13,7 @@ import ( | ||||
| 	"code.gitea.io/gitea/models/unit" | ||||
| 	user_model "code.gitea.io/gitea/models/user" | ||||
| 	"code.gitea.io/gitea/modules/container" | ||||
| 	"code.gitea.io/gitea/modules/optional" | ||||
| 	"code.gitea.io/gitea/modules/setting" | ||||
| 	"code.gitea.io/gitea/modules/structs" | ||||
| 	"code.gitea.io/gitea/modules/util" | ||||
| @ -125,11 +126,11 @@ type SearchRepoOptions struct { | ||||
| 	// None -> include public and private | ||||
| 	// True -> include just private | ||||
| 	// False -> include just public | ||||
| 	IsPrivate util.OptionalBool | ||||
| 	IsPrivate optional.Option[bool] | ||||
| 	// None -> include collaborative AND non-collaborative | ||||
| 	// True -> include just collaborative | ||||
| 	// False -> include just non-collaborative | ||||
| 	Collaborate util.OptionalBool | ||||
| 	Collaborate optional.Option[bool] | ||||
| 	// What type of unit the user can be collaborative in, | ||||
| 	// it is ignored if Collaborate is False. | ||||
| 	// TypeInvalid means any unit type. | ||||
| @ -137,19 +138,19 @@ type SearchRepoOptions struct { | ||||
| 	// None -> include forks AND non-forks | ||||
| 	// True -> include just forks | ||||
| 	// False -> include just non-forks | ||||
| 	Fork util.OptionalBool | ||||
| 	Fork optional.Option[bool] | ||||
| 	// None -> include templates AND non-templates | ||||
| 	// True -> include just templates | ||||
| 	// False -> include just non-templates | ||||
| 	Template util.OptionalBool | ||||
| 	Template optional.Option[bool] | ||||
| 	// None -> include mirrors AND non-mirrors | ||||
| 	// True -> include just mirrors | ||||
| 	// False -> include just non-mirrors | ||||
| 	Mirror util.OptionalBool | ||||
| 	Mirror optional.Option[bool] | ||||
| 	// None -> include archived AND non-archived | ||||
| 	// True -> include just archived | ||||
| 	// False -> include just non-archived | ||||
| 	Archived util.OptionalBool | ||||
| 	Archived optional.Option[bool] | ||||
| 	// only search topic name | ||||
| 	TopicOnly bool | ||||
| 	// only search repositories with specified primary language | ||||
| @ -159,7 +160,7 @@ type SearchRepoOptions struct { | ||||
| 	// None -> include has milestones AND has no milestone | ||||
| 	// True -> include just has milestones | ||||
| 	// False -> include just has no milestone | ||||
| 	HasMilestones util.OptionalBool | ||||
| 	HasMilestones optional.Option[bool] | ||||
| 	// LowerNames represents valid lower names to restrict to | ||||
| 	LowerNames []string | ||||
| 	// When specified true, apply some filters over the conditions: | ||||
| @ -359,12 +360,12 @@ func SearchRepositoryCondition(opts *SearchRepoOptions) builder.Cond { | ||||
| 			))) | ||||
| 	} | ||||
| 
 | ||||
| 	if opts.IsPrivate != util.OptionalBoolNone { | ||||
| 		cond = cond.And(builder.Eq{"is_private": opts.IsPrivate.IsTrue()}) | ||||
| 	if opts.IsPrivate.Has() { | ||||
| 		cond = cond.And(builder.Eq{"is_private": opts.IsPrivate.Value()}) | ||||
| 	} | ||||
| 
 | ||||
| 	if opts.Template != util.OptionalBoolNone { | ||||
| 		cond = cond.And(builder.Eq{"is_template": opts.Template == util.OptionalBoolTrue}) | ||||
| 	if opts.Template.Has() { | ||||
| 		cond = cond.And(builder.Eq{"is_template": opts.Template.Value()}) | ||||
| 	} | ||||
| 
 | ||||
| 	// 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 | ||||
| 	if opts.OwnerID > 0 { | ||||
| 		accessCond := builder.NewCond() | ||||
| 		if opts.Collaborate != util.OptionalBoolTrue { | ||||
| 		if !opts.Collaborate.Value() { | ||||
| 			accessCond = builder.Eq{"owner_id": opts.OwnerID} | ||||
| 		} | ||||
| 
 | ||||
| 		if opts.Collaborate != util.OptionalBoolFalse { | ||||
| 		if opts.Collaborate.ValueOrDefault(true) { | ||||
| 			// A Collaboration is: | ||||
| 
 | ||||
| 			collaborateCond := builder.NewCond() | ||||
| @ -472,31 +473,32 @@ func SearchRepositoryCondition(opts *SearchRepoOptions) builder.Cond { | ||||
| 			Where(builder.Eq{"language": opts.Language}).And(builder.Eq{"is_primary": true}))) | ||||
| 	} | ||||
| 
 | ||||
| 	if opts.Fork != util.OptionalBoolNone || opts.OnlyShowRelevant { | ||||
| 		if opts.OnlyShowRelevant && opts.Fork == util.OptionalBoolNone { | ||||
| 	if opts.Fork.Has() || opts.OnlyShowRelevant { | ||||
| 		if opts.OnlyShowRelevant && !opts.Fork.Has() { | ||||
| 			cond = cond.And(builder.Eq{"is_fork": false}) | ||||
| 		} 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 { | ||||
| 		cond = cond.And(builder.Eq{"is_mirror": opts.Mirror == util.OptionalBoolTrue}) | ||||
| 	if opts.Mirror.Has() { | ||||
| 		cond = cond.And(builder.Eq{"is_mirror": opts.Mirror.Value()}) | ||||
| 	} | ||||
| 
 | ||||
| 	if opts.Actor != nil && opts.Actor.IsRestricted { | ||||
| 		cond = cond.And(AccessibleRepositoryCondition(opts.Actor, unit.TypeInvalid)) | ||||
| 	} | ||||
| 
 | ||||
| 	if opts.Archived != util.OptionalBoolNone { | ||||
| 		cond = cond.And(builder.Eq{"is_archived": opts.Archived == util.OptionalBoolTrue}) | ||||
| 	if opts.Archived.Has() { | ||||
| 		cond = cond.And(builder.Eq{"is_archived": opts.Archived.Value()}) | ||||
| 	} | ||||
| 
 | ||||
| 	switch opts.HasMilestones { | ||||
| 	case util.OptionalBoolTrue: | ||||
| 		cond = cond.And(builder.Gt{"num_milestones": 0}) | ||||
| 	case util.OptionalBoolFalse: | ||||
| 		cond = cond.And(builder.Eq{"num_milestones": 0}.Or(builder.IsNull{"num_milestones"})) | ||||
| 	if opts.HasMilestones.Has() { | ||||
| 		if opts.HasMilestones.Value() { | ||||
| 			cond = cond.And(builder.Gt{"num_milestones": 0}) | ||||
| 		} else { | ||||
| 			cond = cond.And(builder.Eq{"num_milestones": 0}.Or(builder.IsNull{"num_milestones"})) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if opts.OnlyShowRelevant { | ||||
|  | ||||
| @ -10,7 +10,7 @@ import ( | ||||
| 	"code.gitea.io/gitea/models/db" | ||||
| 	repo_model "code.gitea.io/gitea/models/repo" | ||||
| 	"code.gitea.io/gitea/models/unittest" | ||||
| 	"code.gitea.io/gitea/modules/util" | ||||
| 	"code.gitea.io/gitea/modules/optional" | ||||
| 
 | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| ) | ||||
| @ -27,62 +27,62 @@ func getTestCases() []struct { | ||||
| 	}{ | ||||
| 		{ | ||||
| 			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, | ||||
| 		}, | ||||
| 		{ | ||||
| 			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, | ||||
| 		}, | ||||
| 		{ | ||||
| 			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, | ||||
| 		}, | ||||
| 		{ | ||||
| 			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, | ||||
| 		}, | ||||
| 		{ | ||||
| 			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, | ||||
| 		}, | ||||
| 		{ | ||||
| 			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, | ||||
| 		}, | ||||
| 		{ | ||||
| 			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, | ||||
| 		}, | ||||
| 		{ | ||||
| 			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, | ||||
| 		}, | ||||
| 		{ | ||||
| 			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, | ||||
| 		}, | ||||
| 		{ | ||||
| 			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, | ||||
| 		}, | ||||
| 		{ | ||||
| 			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, | ||||
| 		}, | ||||
| 		{ | ||||
| 			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, | ||||
| 		}, | ||||
| 		{ | ||||
| @ -117,32 +117,32 @@ func getTestCases() []struct { | ||||
| 		}, | ||||
| 		{ | ||||
| 			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, | ||||
| 		}, | ||||
| 		{ | ||||
| 			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, | ||||
| 		}, | ||||
| 		{ | ||||
| 			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, | ||||
| 		}, | ||||
| 		{ | ||||
| 			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, | ||||
| 		}, | ||||
| 		{ | ||||
| 			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: 33, | ||||
| 		}, | ||||
| 		{ | ||||
| 			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: 38, | ||||
| 		}, | ||||
| 		{ | ||||
| @ -157,12 +157,12 @@ func getTestCases() []struct { | ||||
| 		}, | ||||
| 		{ | ||||
| 			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: 33, | ||||
| 		}, | ||||
| 		{ | ||||
| 			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, | ||||
| 		}, | ||||
| 		{ | ||||
| @ -190,7 +190,7 @@ func TestSearchRepository(t *testing.T) { | ||||
| 			PageSize: 10, | ||||
| 		}, | ||||
| 		Keyword:     "repo_12", | ||||
| 		Collaborate: util.OptionalBoolFalse, | ||||
| 		Collaborate: optional.Some(false), | ||||
| 	}) | ||||
| 
 | ||||
| 	assert.NoError(t, err) | ||||
| @ -205,7 +205,7 @@ func TestSearchRepository(t *testing.T) { | ||||
| 			PageSize: 10, | ||||
| 		}, | ||||
| 		Keyword:     "test_repo", | ||||
| 		Collaborate: util.OptionalBoolFalse, | ||||
| 		Collaborate: optional.Some(false), | ||||
| 	}) | ||||
| 
 | ||||
| 	assert.NoError(t, err) | ||||
| @ -220,7 +220,7 @@ func TestSearchRepository(t *testing.T) { | ||||
| 		}, | ||||
| 		Keyword:     "repo_13", | ||||
| 		Private:     true, | ||||
| 		Collaborate: util.OptionalBoolFalse, | ||||
| 		Collaborate: optional.Some(false), | ||||
| 	}) | ||||
| 
 | ||||
| 	assert.NoError(t, err) | ||||
| @ -236,7 +236,7 @@ func TestSearchRepository(t *testing.T) { | ||||
| 		}, | ||||
| 		Keyword:     "test_repo", | ||||
| 		Private:     true, | ||||
| 		Collaborate: util.OptionalBoolFalse, | ||||
| 		Collaborate: optional.Some(false), | ||||
| 	}) | ||||
| 
 | ||||
| 	assert.NoError(t, err) | ||||
| @ -257,7 +257,7 @@ func TestSearchRepository(t *testing.T) { | ||||
| 			PageSize: 10, | ||||
| 		}, | ||||
| 		Keyword:            "description_14", | ||||
| 		Collaborate:        util.OptionalBoolFalse, | ||||
| 		Collaborate:        optional.Some(false), | ||||
| 		IncludeDescription: true, | ||||
| 	}) | ||||
| 
 | ||||
| @ -274,7 +274,7 @@ func TestSearchRepository(t *testing.T) { | ||||
| 			PageSize: 10, | ||||
| 		}, | ||||
| 		Keyword:            "description_14", | ||||
| 		Collaborate:        util.OptionalBoolFalse, | ||||
| 		Collaborate:        optional.Some(false), | ||||
| 		IncludeDescription: false, | ||||
| 	}) | ||||
| 
 | ||||
| @ -327,30 +327,25 @@ func TestSearchRepository(t *testing.T) { | ||||
| 						assert.False(t, repo.IsPrivate) | ||||
| 					} | ||||
| 
 | ||||
| 					if testCase.opts.Fork == util.OptionalBoolTrue && testCase.opts.Mirror == util.OptionalBoolTrue { | ||||
| 						assert.True(t, repo.IsFork || repo.IsMirror) | ||||
| 					if testCase.opts.Fork.Value() && testCase.opts.Mirror.Value() { | ||||
| 						assert.True(t, repo.IsFork && repo.IsMirror) | ||||
| 					} else { | ||||
| 						switch testCase.opts.Fork { | ||||
| 						case util.OptionalBoolFalse: | ||||
| 							assert.False(t, repo.IsFork) | ||||
| 						case util.OptionalBoolTrue: | ||||
| 							assert.True(t, repo.IsFork) | ||||
| 						if testCase.opts.Fork.Has() { | ||||
| 							assert.Equal(t, testCase.opts.Fork.Value(), repo.IsFork) | ||||
| 						} | ||||
| 
 | ||||
| 						switch testCase.opts.Mirror { | ||||
| 						case util.OptionalBoolFalse: | ||||
| 							assert.False(t, repo.IsMirror) | ||||
| 						case util.OptionalBoolTrue: | ||||
| 							assert.True(t, repo.IsMirror) | ||||
| 						if testCase.opts.Mirror.Has() { | ||||
| 							assert.Equal(t, testCase.opts.Mirror.Value(), repo.IsMirror) | ||||
| 						} | ||||
| 					} | ||||
| 
 | ||||
| 					if testCase.opts.OwnerID > 0 && !testCase.opts.AllPublic { | ||||
| 						switch testCase.opts.Collaborate { | ||||
| 						case util.OptionalBoolFalse: | ||||
| 							assert.Equal(t, testCase.opts.OwnerID, repo.Owner.ID) | ||||
| 						case util.OptionalBoolTrue: | ||||
| 							assert.NotEqual(t, testCase.opts.OwnerID, repo.Owner.ID) | ||||
| 						if testCase.opts.Collaborate.Has() { | ||||
| 							if testCase.opts.Collaborate.Value() { | ||||
| 								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/modules/base" | ||||
| 	"code.gitea.io/gitea/modules/log" | ||||
| 	"code.gitea.io/gitea/modules/optional" | ||||
| 	"code.gitea.io/gitea/modules/setting" | ||||
| 	"code.gitea.io/gitea/modules/util" | ||||
| 	"code.gitea.io/gitea/modules/validation" | ||||
| @ -416,8 +417,8 @@ type SearchEmailOptions struct { | ||||
| 	db.ListOptions | ||||
| 	Keyword     string | ||||
| 	SortType    SearchEmailOrderBy | ||||
| 	IsPrimary   util.OptionalBool | ||||
| 	IsActivated util.OptionalBool | ||||
| 	IsPrimary   optional.Option[bool] | ||||
| 	IsActivated optional.Option[bool] | ||||
| } | ||||
| 
 | ||||
| // SearchEmailResult is an e-mail address found in the user or email_address table | ||||
| @ -444,18 +445,12 @@ func SearchEmails(ctx context.Context, opts *SearchEmailOptions) ([]*SearchEmail | ||||
| 		)) | ||||
| 	} | ||||
| 
 | ||||
| 	switch { | ||||
| 	case opts.IsPrimary.IsTrue(): | ||||
| 		cond = cond.And(builder.Eq{"email_address.is_primary": true}) | ||||
| 	case opts.IsPrimary.IsFalse(): | ||||
| 		cond = cond.And(builder.Eq{"email_address.is_primary": false}) | ||||
| 	if opts.IsPrimary.Has() { | ||||
| 		cond = cond.And(builder.Eq{"email_address.is_primary": opts.IsPrimary.Value()}) | ||||
| 	} | ||||
| 
 | ||||
| 	switch { | ||||
| 	case opts.IsActivated.IsTrue(): | ||||
| 		cond = cond.And(builder.Eq{"email_address.is_activated": true}) | ||||
| 	case opts.IsActivated.IsFalse(): | ||||
| 		cond = cond.And(builder.Eq{"email_address.is_activated": false}) | ||||
| 	if opts.IsActivated.Has() { | ||||
| 		cond = cond.And(builder.Eq{"email_address.is_activated": opts.IsActivated.Value()}) | ||||
| 	} | ||||
| 
 | ||||
| 	count, err := db.GetEngine(ctx).Join("INNER", "`user`", "`user`.ID = email_address.uid"). | ||||
|  | ||||
| @ -9,7 +9,7 @@ import ( | ||||
| 	"code.gitea.io/gitea/models/db" | ||||
| 	"code.gitea.io/gitea/models/unittest" | ||||
| 	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" | ||||
| ) | ||||
| @ -128,14 +128,14 @@ func TestListEmails(t *testing.T) { | ||||
| 	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) | ||||
| 	opts = &user_model.SearchEmailOptions{IsPrimary: util.OptionalBoolTrue} | ||||
| 	opts = &user_model.SearchEmailOptions{IsPrimary: optional.Some(true)} | ||||
| 	emails, _, err = user_model.SearchEmails(db.DefaultContext, opts) | ||||
| 	assert.NoError(t, err) | ||||
| 	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 })) | ||||
| 
 | ||||
| 	// 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) | ||||
| 	assert.NoError(t, err) | ||||
| 	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/modules/container" | ||||
| 	"code.gitea.io/gitea/modules/optional" | ||||
| 	"code.gitea.io/gitea/modules/structs" | ||||
| 	"code.gitea.io/gitea/modules/util" | ||||
| 
 | ||||
| 	"xorm.io/builder" | ||||
| 	"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 | ||||
| 
 | ||||
| 	IsActive           util.OptionalBool | ||||
| 	IsAdmin            util.OptionalBool | ||||
| 	IsRestricted       util.OptionalBool | ||||
| 	IsTwoFactorEnabled util.OptionalBool | ||||
| 	IsProhibitLogin    util.OptionalBool | ||||
| 	IsActive           optional.Option[bool] | ||||
| 	IsAdmin            optional.Option[bool] | ||||
| 	IsRestricted       optional.Option[bool] | ||||
| 	IsTwoFactorEnabled optional.Option[bool] | ||||
| 	IsProhibitLogin    optional.Option[bool] | ||||
| 	IncludeReserved    bool | ||||
| 
 | ||||
| 	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}) | ||||
| 	} | ||||
| 
 | ||||
| 	if !opts.IsActive.IsNone() { | ||||
| 		cond = cond.And(builder.Eq{"is_active": opts.IsActive.IsTrue()}) | ||||
| 	if opts.IsActive.Has() { | ||||
| 		cond = cond.And(builder.Eq{"is_active": opts.IsActive.Value()}) | ||||
| 	} | ||||
| 
 | ||||
| 	if !opts.IsAdmin.IsNone() { | ||||
| 		cond = cond.And(builder.Eq{"is_admin": opts.IsAdmin.IsTrue()}) | ||||
| 	if opts.IsAdmin.Has() { | ||||
| 		cond = cond.And(builder.Eq{"is_admin": opts.IsAdmin.Value()}) | ||||
| 	} | ||||
| 
 | ||||
| 	if !opts.IsRestricted.IsNone() { | ||||
| 		cond = cond.And(builder.Eq{"is_restricted": opts.IsRestricted.IsTrue()}) | ||||
| 	if opts.IsRestricted.Has() { | ||||
| 		cond = cond.And(builder.Eq{"is_restricted": opts.IsRestricted.Value()}) | ||||
| 	} | ||||
| 
 | ||||
| 	if !opts.IsProhibitLogin.IsNone() { | ||||
| 		cond = cond.And(builder.Eq{"prohibit_login": opts.IsProhibitLogin.IsTrue()}) | ||||
| 	if opts.IsProhibitLogin.Has() { | ||||
| 		cond = cond.And(builder.Eq{"prohibit_login": opts.IsProhibitLogin.Value()}) | ||||
| 	} | ||||
| 
 | ||||
| 	e := db.GetEngine(ctx) | ||||
| 	if opts.IsTwoFactorEnabled.IsNone() { | ||||
| 	if !opts.IsTwoFactorEnabled.Has() { | ||||
| 		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. | ||||
| 	// 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) | ||||
| 	if opts.IsTwoFactorEnabled.IsTrue() { | ||||
| 	if opts.IsTwoFactorEnabled.Value() { | ||||
| 		cond = cond.And(builder.Expr("two_factor.uid IS NOT NULL")) | ||||
| 	} else { | ||||
| 		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() | ||||
| 	count, err := sessCount.Count(new(User)) | ||||
| 	if err != nil { | ||||
| 		return nil, 0, fmt.Errorf("Count: %w", err) | ||||
| 		return nil, 0, fmt.Errorf("count: %w", err) | ||||
| 	} | ||||
| 
 | ||||
| 	if len(opts.OrderBy) == 0 { | ||||
|  | ||||
| @ -16,10 +16,10 @@ import ( | ||||
| 	"code.gitea.io/gitea/models/unittest" | ||||
| 	user_model "code.gitea.io/gitea/models/user" | ||||
| 	"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/structs" | ||||
| 	"code.gitea.io/gitea/modules/timeutil" | ||||
| 	"code.gitea.io/gitea/modules/util" | ||||
| 
 | ||||
| 	"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}}, | ||||
| 		[]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}) | ||||
| 
 | ||||
| 	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}) | ||||
| 
 | ||||
| 	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}) | ||||
| 
 | ||||
| 	// 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}) | ||||
| 
 | ||||
| 	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}) | ||||
| 
 | ||||
| 	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}) | ||||
| 
 | ||||
| 	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}) | ||||
| 
 | ||||
| 	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}) | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -20,10 +20,10 @@ import ( | ||||
| 	"code.gitea.io/gitea/modules/indexer/issues/internal" | ||||
| 	"code.gitea.io/gitea/modules/indexer/issues/meilisearch" | ||||
| 	"code.gitea.io/gitea/modules/log" | ||||
| 	"code.gitea.io/gitea/modules/optional" | ||||
| 	"code.gitea.io/gitea/modules/process" | ||||
| 	"code.gitea.io/gitea/modules/queue" | ||||
| 	"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. | ||||
| @ -220,7 +220,7 @@ func PopulateIssueIndexer(ctx context.Context) error { | ||||
| 			ListOptions: db_model.ListOptions{Page: page, PageSize: repo_model.RepositoryListDefaultPageSize}, | ||||
| 			OrderBy:     db_model.SearchOrderByID, | ||||
| 			Private:     true, | ||||
| 			Collaborate: util.OptionalBoolFalse, | ||||
| 			Collaborate: optional.Some(false), | ||||
| 		}) | ||||
| 		if err != nil { | ||||
| 			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.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 | ||||
| 	assert.False(t, optional.FromPtr(ptr).Has()) | ||||
| 
 | ||||
|  | ||||
| @ -68,13 +68,13 @@ func OptionalBoolOf(b bool) OptionalBool { | ||||
| 	return OptionalBoolFalse | ||||
| } | ||||
| 
 | ||||
| // OptionalBoolParse get the corresponding OptionalBool of a string using strconv.ParseBool | ||||
| func OptionalBoolParse(s string) OptionalBool { | ||||
| 	b, e := strconv.ParseBool(s) | ||||
| // OptionalBoolParse get the corresponding optional.Option[bool] of a string using strconv.ParseBool | ||||
| func OptionalBoolParse(s string) optional.Option[bool] { | ||||
| 	v, e := strconv.ParseBool(s) | ||||
| 	if e != nil { | ||||
| 		return OptionalBoolNone | ||||
| 		return optional.None[bool]() | ||||
| 	} | ||||
| 	return OptionalBoolOf(b) | ||||
| 	return optional.Some(v) | ||||
| } | ||||
| 
 | ||||
| // IsEmptyString checks if the provided string is empty | ||||
|  | ||||
| @ -8,6 +8,8 @@ import ( | ||||
| 	"strings" | ||||
| 	"testing" | ||||
| 
 | ||||
| 	"code.gitea.io/gitea/modules/optional" | ||||
| 
 | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| ) | ||||
| 
 | ||||
| @ -173,17 +175,17 @@ func Test_RandomBytes(t *testing.T) { | ||||
| 	assert.NotEqual(t, bytes3, bytes4) | ||||
| } | ||||
| 
 | ||||
| func Test_OptionalBool(t *testing.T) { | ||||
| 	assert.Equal(t, OptionalBoolNone, OptionalBoolParse("")) | ||||
| 	assert.Equal(t, OptionalBoolNone, OptionalBoolParse("x")) | ||||
| func TestOptionalBoolParse(t *testing.T) { | ||||
| 	assert.Equal(t, optional.None[bool](), OptionalBoolParse("")) | ||||
| 	assert.Equal(t, optional.None[bool](), OptionalBoolParse("x")) | ||||
| 
 | ||||
| 	assert.Equal(t, OptionalBoolFalse, OptionalBoolParse("0")) | ||||
| 	assert.Equal(t, OptionalBoolFalse, OptionalBoolParse("f")) | ||||
| 	assert.Equal(t, OptionalBoolFalse, OptionalBoolParse("False")) | ||||
| 	assert.Equal(t, optional.Some(false), OptionalBoolParse("0")) | ||||
| 	assert.Equal(t, optional.Some(false), OptionalBoolParse("f")) | ||||
| 	assert.Equal(t, optional.Some(false), OptionalBoolParse("False")) | ||||
| 
 | ||||
| 	assert.Equal(t, OptionalBoolTrue, OptionalBoolParse("1")) | ||||
| 	assert.Equal(t, OptionalBoolTrue, OptionalBoolParse("t")) | ||||
| 	assert.Equal(t, OptionalBoolTrue, OptionalBoolParse("True")) | ||||
| 	assert.Equal(t, optional.Some(true), OptionalBoolParse("1")) | ||||
| 	assert.Equal(t, optional.Some(true), OptionalBoolParse("t")) | ||||
| 	assert.Equal(t, optional.Some(true), OptionalBoolParse("True")) | ||||
| } | ||||
| 
 | ||||
| // Test case for any function which accepts and returns a single string. | ||||
|  | ||||
| @ -19,6 +19,7 @@ import ( | ||||
| 	"code.gitea.io/gitea/models/unit" | ||||
| 	user_model "code.gitea.io/gitea/models/user" | ||||
| 	issue_indexer "code.gitea.io/gitea/modules/indexer/issues" | ||||
| 	"code.gitea.io/gitea/modules/optional" | ||||
| 	"code.gitea.io/gitea/modules/setting" | ||||
| 	api "code.gitea.io/gitea/modules/structs" | ||||
| 	"code.gitea.io/gitea/modules/timeutil" | ||||
| @ -142,7 +143,7 @@ func SearchIssues(ctx *context.APIContext) { | ||||
| 			Private:     false, | ||||
| 			AllPublic:   true, | ||||
| 			TopicOnly:   false, | ||||
| 			Collaborate: util.OptionalBoolNone, | ||||
| 			Collaborate: optional.None[bool](), | ||||
| 			// 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 | ||||
| 			OrderBy: db.SearchOrderByAlphabetically, | ||||
| @ -165,7 +166,7 @@ func SearchIssues(ctx *context.APIContext) { | ||||
| 			opts.OwnerID = owner.ID | ||||
| 			opts.AllLimited = false | ||||
| 			opts.AllPublic = false | ||||
| 			opts.Collaborate = util.OptionalBoolFalse | ||||
| 			opts.Collaborate = optional.Some(false) | ||||
| 		} | ||||
| 		if ctx.FormString("team") != "" { | ||||
| 			if ctx.FormString("owner") == "" { | ||||
|  | ||||
| @ -24,10 +24,10 @@ import ( | ||||
| 	"code.gitea.io/gitea/modules/gitrepo" | ||||
| 	"code.gitea.io/gitea/modules/label" | ||||
| 	"code.gitea.io/gitea/modules/log" | ||||
| 	"code.gitea.io/gitea/modules/optional" | ||||
| 	repo_module "code.gitea.io/gitea/modules/repository" | ||||
| 	"code.gitea.io/gitea/modules/setting" | ||||
| 	api "code.gitea.io/gitea/modules/structs" | ||||
| 	"code.gitea.io/gitea/modules/util" | ||||
| 	"code.gitea.io/gitea/modules/validation" | ||||
| 	"code.gitea.io/gitea/modules/web" | ||||
| 	"code.gitea.io/gitea/routers/api/v1/utils" | ||||
| @ -135,33 +135,33 @@ func Search(ctx *context.APIContext) { | ||||
| 		PriorityOwnerID:    ctx.FormInt64("priority_owner_id"), | ||||
| 		TeamID:             ctx.FormInt64("team_id"), | ||||
| 		TopicOnly:          ctx.FormBool("topic"), | ||||
| 		Collaborate:        util.OptionalBoolNone, | ||||
| 		Collaborate:        optional.None[bool](), | ||||
| 		Private:            ctx.IsSigned && (ctx.FormString("private") == "" || ctx.FormBool("private")), | ||||
| 		Template:           util.OptionalBoolNone, | ||||
| 		Template:           optional.None[bool](), | ||||
| 		StarredByID:        ctx.FormInt64("starredBy"), | ||||
| 		IncludeDescription: ctx.FormBool("includeDesc"), | ||||
| 	} | ||||
| 
 | ||||
| 	if ctx.FormString("template") != "" { | ||||
| 		opts.Template = util.OptionalBoolOf(ctx.FormBool("template")) | ||||
| 		opts.Template = optional.Some(ctx.FormBool("template")) | ||||
| 	} | ||||
| 
 | ||||
| 	if ctx.FormBool("exclusive") { | ||||
| 		opts.Collaborate = util.OptionalBoolFalse | ||||
| 		opts.Collaborate = optional.Some(false) | ||||
| 	} | ||||
| 
 | ||||
| 	mode := ctx.FormString("mode") | ||||
| 	switch mode { | ||||
| 	case "source": | ||||
| 		opts.Fork = util.OptionalBoolFalse | ||||
| 		opts.Mirror = util.OptionalBoolFalse | ||||
| 		opts.Fork = optional.Some(false) | ||||
| 		opts.Mirror = optional.Some(false) | ||||
| 	case "fork": | ||||
| 		opts.Fork = util.OptionalBoolTrue | ||||
| 		opts.Fork = optional.Some(true) | ||||
| 	case "mirror": | ||||
| 		opts.Mirror = util.OptionalBoolTrue | ||||
| 		opts.Mirror = optional.Some(true) | ||||
| 	case "collaborative": | ||||
| 		opts.Mirror = util.OptionalBoolFalse | ||||
| 		opts.Collaborate = util.OptionalBoolTrue | ||||
| 		opts.Mirror = optional.Some(false) | ||||
| 		opts.Collaborate = optional.Some(true) | ||||
| 	case "": | ||||
| 	default: | ||||
| 		ctx.Error(http.StatusUnprocessableEntity, "", fmt.Errorf("Invalid search mode: \"%s\"", mode)) | ||||
| @ -169,11 +169,11 @@ func Search(ctx *context.APIContext) { | ||||
| 	} | ||||
| 
 | ||||
| 	if ctx.FormString("archived") != "" { | ||||
| 		opts.Archived = util.OptionalBoolOf(ctx.FormBool("archived")) | ||||
| 		opts.Archived = optional.Some(ctx.FormBool("archived")) | ||||
| 	} | ||||
| 
 | ||||
| 	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") | ||||
|  | ||||
| @ -12,8 +12,8 @@ import ( | ||||
| 	user_model "code.gitea.io/gitea/models/user" | ||||
| 	"code.gitea.io/gitea/modules/base" | ||||
| 	"code.gitea.io/gitea/modules/log" | ||||
| 	"code.gitea.io/gitea/modules/optional" | ||||
| 	"code.gitea.io/gitea/modules/setting" | ||||
| 	"code.gitea.io/gitea/modules/util" | ||||
| 	"code.gitea.io/gitea/services/context" | ||||
| ) | ||||
| 
 | ||||
| @ -68,10 +68,10 @@ func Emails(ctx *context.Context) { | ||||
| 	opts.Keyword = ctx.FormTrim("q") | ||||
| 	opts.SortType = orderBy | ||||
| 	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 { | ||||
| 		opts.IsPrimary = util.OptionalBoolOf(ctx.FormBool("primary")) | ||||
| 		opts.IsPrimary = optional.Some(ctx.FormBool("primary")) | ||||
| 	} | ||||
| 
 | ||||
| 	if len(opts.Keyword) == 0 || isKeywordValid(opts.Keyword) { | ||||
|  | ||||
| @ -276,7 +276,7 @@ func ViewUser(ctx *context.Context) { | ||||
| 		OwnerID:     u.ID, | ||||
| 		OrderBy:     db.SearchOrderByAlphabetically, | ||||
| 		Private:     true, | ||||
| 		Collaborate: util.OptionalBoolFalse, | ||||
| 		Collaborate: optional.Some(false), | ||||
| 	}) | ||||
| 	if err != nil { | ||||
| 		ctx.ServerError("SearchRepository", err) | ||||
|  | ||||
| @ -12,10 +12,10 @@ import ( | ||||
| 	"code.gitea.io/gitea/modules/base" | ||||
| 	"code.gitea.io/gitea/modules/container" | ||||
| 	"code.gitea.io/gitea/modules/log" | ||||
| 	"code.gitea.io/gitea/modules/optional" | ||||
| 	"code.gitea.io/gitea/modules/setting" | ||||
| 	"code.gitea.io/gitea/modules/sitemap" | ||||
| 	"code.gitea.io/gitea/modules/structs" | ||||
| 	"code.gitea.io/gitea/modules/util" | ||||
| 	"code.gitea.io/gitea/services/context" | ||||
| ) | ||||
| 
 | ||||
| @ -155,7 +155,7 @@ func Users(ctx *context.Context) { | ||||
| 		Actor:       ctx.Doer, | ||||
| 		Type:        user_model.UserTypeIndividual, | ||||
| 		ListOptions: db.ListOptions{PageSize: setting.UI.ExplorePagingNum}, | ||||
| 		IsActive:    util.OptionalBoolTrue, | ||||
| 		IsActive:    optional.Some(true), | ||||
| 		Visible:     []structs.VisibleType{structs.VisibleTypePublic, structs.VisibleTypeLimited, structs.VisibleTypePrivate}, | ||||
| 
 | ||||
| 		SupportedSortOrders: supportedSortOrders, | ||||
|  | ||||
| @ -13,10 +13,10 @@ import ( | ||||
| 	user_model "code.gitea.io/gitea/models/user" | ||||
| 	"code.gitea.io/gitea/modules/base" | ||||
| 	"code.gitea.io/gitea/modules/log" | ||||
| 	"code.gitea.io/gitea/modules/optional" | ||||
| 	"code.gitea.io/gitea/modules/setting" | ||||
| 	"code.gitea.io/gitea/modules/sitemap" | ||||
| 	"code.gitea.io/gitea/modules/structs" | ||||
| 	"code.gitea.io/gitea/modules/util" | ||||
| 	"code.gitea.io/gitea/modules/web/middleware" | ||||
| 	"code.gitea.io/gitea/routers/web/auth" | ||||
| 	"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{ | ||||
| 			Type:        user_model.UserTypeIndividual, | ||||
| 			ListOptions: db.ListOptions{PageSize: 1}, | ||||
| 			IsActive:    util.OptionalBoolTrue, | ||||
| 			IsActive:    optional.Some(true), | ||||
| 			Visible:     []structs.VisibleType{structs.VisibleTypePublic}, | ||||
| 		}) | ||||
| 		if err != nil { | ||||
|  | ||||
| @ -38,6 +38,7 @@ import ( | ||||
| 	"code.gitea.io/gitea/modules/log" | ||||
| 	"code.gitea.io/gitea/modules/markup" | ||||
| 	"code.gitea.io/gitea/modules/markup/markdown" | ||||
| 	"code.gitea.io/gitea/modules/optional" | ||||
| 	repo_module "code.gitea.io/gitea/modules/repository" | ||||
| 	"code.gitea.io/gitea/modules/setting" | ||||
| 	api "code.gitea.io/gitea/modules/structs" | ||||
| @ -2519,7 +2520,7 @@ func SearchIssues(ctx *context.Context) { | ||||
| 			Private:     false, | ||||
| 			AllPublic:   true, | ||||
| 			TopicOnly:   false, | ||||
| 			Collaborate: util.OptionalBoolNone, | ||||
| 			Collaborate: optional.None[bool](), | ||||
| 			// 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 | ||||
| 			OrderBy: db.SearchOrderByAlphabetically, | ||||
| @ -2542,7 +2543,7 @@ func SearchIssues(ctx *context.Context) { | ||||
| 			opts.OwnerID = owner.ID | ||||
| 			opts.AllLimited = false | ||||
| 			opts.AllPublic = false | ||||
| 			opts.Collaborate = util.OptionalBoolFalse | ||||
| 			opts.Collaborate = optional.Some(false) | ||||
| 		} | ||||
| 		if ctx.FormString("team") != "" { | ||||
| 			if ctx.FormString("owner") == "" { | ||||
|  | ||||
| @ -553,33 +553,33 @@ func SearchRepo(ctx *context.Context) { | ||||
| 		PriorityOwnerID:    ctx.FormInt64("priority_owner_id"), | ||||
| 		TeamID:             ctx.FormInt64("team_id"), | ||||
| 		TopicOnly:          ctx.FormBool("topic"), | ||||
| 		Collaborate:        util.OptionalBoolNone, | ||||
| 		Collaborate:        optional.None[bool](), | ||||
| 		Private:            ctx.IsSigned && (ctx.FormString("private") == "" || ctx.FormBool("private")), | ||||
| 		Template:           util.OptionalBoolNone, | ||||
| 		Template:           optional.None[bool](), | ||||
| 		StarredByID:        ctx.FormInt64("starredBy"), | ||||
| 		IncludeDescription: ctx.FormBool("includeDesc"), | ||||
| 	} | ||||
| 
 | ||||
| 	if ctx.FormString("template") != "" { | ||||
| 		opts.Template = util.OptionalBoolOf(ctx.FormBool("template")) | ||||
| 		opts.Template = optional.Some(ctx.FormBool("template")) | ||||
| 	} | ||||
| 
 | ||||
| 	if ctx.FormBool("exclusive") { | ||||
| 		opts.Collaborate = util.OptionalBoolFalse | ||||
| 		opts.Collaborate = optional.Some(false) | ||||
| 	} | ||||
| 
 | ||||
| 	mode := ctx.FormString("mode") | ||||
| 	switch mode { | ||||
| 	case "source": | ||||
| 		opts.Fork = util.OptionalBoolFalse | ||||
| 		opts.Mirror = util.OptionalBoolFalse | ||||
| 		opts.Fork = optional.Some(false) | ||||
| 		opts.Mirror = optional.Some(false) | ||||
| 	case "fork": | ||||
| 		opts.Fork = util.OptionalBoolTrue | ||||
| 		opts.Fork = optional.Some(true) | ||||
| 	case "mirror": | ||||
| 		opts.Mirror = util.OptionalBoolTrue | ||||
| 		opts.Mirror = optional.Some(true) | ||||
| 	case "collaborative": | ||||
| 		opts.Mirror = util.OptionalBoolFalse | ||||
| 		opts.Collaborate = util.OptionalBoolTrue | ||||
| 		opts.Mirror = optional.Some(false) | ||||
| 		opts.Collaborate = optional.Some(true) | ||||
| 	case "": | ||||
| 	default: | ||||
| 		ctx.Error(http.StatusUnprocessableEntity, fmt.Sprintf("Invalid search mode: \"%s\"", mode)) | ||||
| @ -587,11 +587,11 @@ func SearchRepo(ctx *context.Context) { | ||||
| 	} | ||||
| 
 | ||||
| 	if ctx.FormString("archived") != "" { | ||||
| 		opts.Archived = util.OptionalBoolOf(ctx.FormBool("archived")) | ||||
| 		opts.Archived = optional.Some(ctx.FormBool("archived")) | ||||
| 	} | ||||
| 
 | ||||
| 	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") | ||||
|  | ||||
| @ -16,6 +16,7 @@ import ( | ||||
| 	"code.gitea.io/gitea/modules/git" | ||||
| 	"code.gitea.io/gitea/modules/gitrepo" | ||||
| 	"code.gitea.io/gitea/modules/log" | ||||
| 	"code.gitea.io/gitea/modules/optional" | ||||
| 	"code.gitea.io/gitea/modules/setting" | ||||
| 	"code.gitea.io/gitea/modules/util" | ||||
| 	"code.gitea.io/gitea/services/context" | ||||
| @ -114,7 +115,7 @@ func LoadHeaderCount(ctx *context.Context) error { | ||||
| 		Actor:              ctx.Doer, | ||||
| 		OwnerID:            ctx.ContextUser.ID, | ||||
| 		Private:            ctx.IsSigned, | ||||
| 		Collaborate:        util.OptionalBoolFalse, | ||||
| 		Collaborate:        optional.Some(false), | ||||
| 		IncludeDescription: setting.UI.SearchRepoDescription, | ||||
| 	}) | ||||
| 	if err != nil { | ||||
|  | ||||
| @ -28,6 +28,7 @@ import ( | ||||
| 	"code.gitea.io/gitea/modules/log" | ||||
| 	"code.gitea.io/gitea/modules/markup" | ||||
| 	"code.gitea.io/gitea/modules/markup/markdown" | ||||
| 	"code.gitea.io/gitea/modules/optional" | ||||
| 	"code.gitea.io/gitea/modules/setting" | ||||
| 	"code.gitea.io/gitea/modules/util" | ||||
| 	"code.gitea.io/gitea/routers/web/feed" | ||||
| @ -161,8 +162,8 @@ func Milestones(ctx *context.Context) { | ||||
| 		Private:       true, | ||||
| 		AllPublic:     false, // Include also all public repositories of users and public organisations | ||||
| 		AllLimited:    false, // Include also all public repositories of limited organisations | ||||
| 		Archived:      util.OptionalBoolFalse, | ||||
| 		HasMilestones: util.OptionalBoolTrue, // Just needs display repos has milestones | ||||
| 		Archived:      optional.Some(false), | ||||
| 		HasMilestones: optional.Some(true), // Just needs display repos has milestones | ||||
| 	} | ||||
| 
 | ||||
| 	if ctxUser.IsOrganization() && ctx.Org.Team != nil { | ||||
| @ -465,9 +466,9 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) { | ||||
| 		Private:     true, | ||||
| 		AllPublic:   false, | ||||
| 		AllLimited:  false, | ||||
| 		Collaborate: util.OptionalBoolNone, | ||||
| 		Collaborate: optional.None[bool](), | ||||
| 		UnitType:    unitType, | ||||
| 		Archived:    util.OptionalBoolFalse, | ||||
| 		Archived:    optional.Some(false), | ||||
| 	} | ||||
| 	if team != nil { | ||||
| 		repoOpts.TeamID = team.ID | ||||
|  | ||||
| @ -17,6 +17,7 @@ import ( | ||||
| 	repo_model "code.gitea.io/gitea/models/repo" | ||||
| 	"code.gitea.io/gitea/modules/base" | ||||
| 	"code.gitea.io/gitea/modules/log" | ||||
| 	"code.gitea.io/gitea/modules/optional" | ||||
| 	"code.gitea.io/gitea/modules/setting" | ||||
| 	"code.gitea.io/gitea/modules/structs" | ||||
| 	"code.gitea.io/gitea/modules/util" | ||||
| @ -399,7 +400,7 @@ func NotificationWatching(ctx *context.Context) { | ||||
| 		OrderBy:            orderBy, | ||||
| 		Private:            ctx.IsSigned, | ||||
| 		WatchedByID:        ctx.Doer.ID, | ||||
| 		Collaborate:        util.OptionalBoolFalse, | ||||
| 		Collaborate:        optional.Some(false), | ||||
| 		TopicOnly:          ctx.FormBool("topic"), | ||||
| 		IncludeDescription: setting.UI.SearchRepoDescription, | ||||
| 	}) | ||||
|  | ||||
| @ -19,6 +19,7 @@ import ( | ||||
| 	"code.gitea.io/gitea/modules/log" | ||||
| 	"code.gitea.io/gitea/modules/markup" | ||||
| 	"code.gitea.io/gitea/modules/markup/markdown" | ||||
| 	"code.gitea.io/gitea/modules/optional" | ||||
| 	"code.gitea.io/gitea/modules/setting" | ||||
| 	"code.gitea.io/gitea/modules/util" | ||||
| 	"code.gitea.io/gitea/routers/web/feed" | ||||
| @ -203,7 +204,7 @@ func prepareUserProfileTabData(ctx *context.Context, showPrivate bool, profileDb | ||||
| 			OrderBy:            orderBy, | ||||
| 			Private:            ctx.IsSigned, | ||||
| 			StarredByID:        ctx.ContextUser.ID, | ||||
| 			Collaborate:        util.OptionalBoolFalse, | ||||
| 			Collaborate:        optional.Some(false), | ||||
| 			TopicOnly:          topicOnly, | ||||
| 			Language:           language, | ||||
| 			IncludeDescription: setting.UI.SearchRepoDescription, | ||||
| @ -225,7 +226,7 @@ func prepareUserProfileTabData(ctx *context.Context, showPrivate bool, profileDb | ||||
| 			OrderBy:            orderBy, | ||||
| 			Private:            ctx.IsSigned, | ||||
| 			WatchedByID:        ctx.ContextUser.ID, | ||||
| 			Collaborate:        util.OptionalBoolFalse, | ||||
| 			Collaborate:        optional.Some(false), | ||||
| 			TopicOnly:          topicOnly, | ||||
| 			Language:           language, | ||||
| 			IncludeDescription: setting.UI.SearchRepoDescription, | ||||
| @ -270,7 +271,7 @@ func prepareUserProfileTabData(ctx *context.Context, showPrivate bool, profileDb | ||||
| 			OwnerID:            ctx.ContextUser.ID, | ||||
| 			OrderBy:            orderBy, | ||||
| 			Private:            ctx.IsSigned, | ||||
| 			Collaborate:        util.OptionalBoolFalse, | ||||
| 			Collaborate:        optional.Some(false), | ||||
| 			TopicOnly:          topicOnly, | ||||
| 			Language:           language, | ||||
| 			IncludeDescription: setting.UI.SearchRepoDescription, | ||||
|  | ||||
| @ -8,7 +8,6 @@ import ( | ||||
| 
 | ||||
| 	"code.gitea.io/gitea/models/db" | ||||
| 	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/convert" | ||||
| ) | ||||
| @ -25,7 +24,7 @@ func Search(ctx *context.Context) { | ||||
| 		Keyword:     ctx.FormTrim("q"), | ||||
| 		UID:         ctx.FormInt64("uid"), | ||||
| 		Type:        user_model.UserTypeIndividual, | ||||
| 		IsActive:    util.OptionalBoolFromGeneric(ctx.FormOptionalBool("active")), | ||||
| 		IsActive:    ctx.FormOptionalBool("active"), | ||||
| 		ListOptions: listOptions, | ||||
| 	}) | ||||
| 	if err != nil { | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 6543
						6543