Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add user/organization code search #19977

Merged
merged 4 commits into from
Oct 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 20 additions & 10 deletions models/repo/repo_list.go
Original file line number Diff line number Diff line change
Expand Up @@ -593,6 +593,16 @@ func searchRepositoryByCondition(ctx context.Context, opts *SearchRepoOptions, c
return sess, count, nil
}

// SearchRepositoryIDsByCondition search repository IDs by given condition.
func SearchRepositoryIDsByCondition(ctx context.Context, cond builder.Cond) ([]int64, error) {
repoIDs := make([]int64, 0, 10)
return repoIDs, db.GetEngine(ctx).
Table("repository").
Cols("id").
Where(cond).
Find(&repoIDs)
}

// AccessibleRepositoryCondition takes a user a returns a condition for checking if a repository is accessible
func AccessibleRepositoryCondition(user *user_model.User, unitType unit.Type) builder.Cond {
cond := builder.NewCond()
Expand Down Expand Up @@ -680,16 +690,16 @@ func AccessibleRepoIDsQuery(user *user_model.User) *builder.Builder {
}

// FindUserCodeAccessibleRepoIDs finds all at Code level accessible repositories' ID by the user's id
func FindUserCodeAccessibleRepoIDs(user *user_model.User) ([]int64, error) {
repoIDs := make([]int64, 0, 10)
if err := db.GetEngine(db.DefaultContext).
Table("repository").
Cols("id").
Where(AccessibleRepositoryCondition(user, unit.TypeCode)).
Find(&repoIDs); err != nil {
return nil, fmt.Errorf("FindUserCodeAccesibleRepoIDs: %v", err)
}
return repoIDs, nil
func FindUserCodeAccessibleRepoIDs(ctx context.Context, user *user_model.User) ([]int64, error) {
return SearchRepositoryIDsByCondition(ctx, AccessibleRepositoryCondition(user, unit.TypeCode))
}

// FindUserCodeAccessibleOwnerRepoIDs finds all repository IDs for the given owner whose code the user can see.
func FindUserCodeAccessibleOwnerRepoIDs(ctx context.Context, ownerID int64, user *user_model.User) ([]int64, error) {
return SearchRepositoryIDsByCondition(ctx, builder.NewCond().And(
builder.Eq{"owner_id": ownerID},
AccessibleRepositoryCondition(user, unit.TypeCode),
))
lafriks marked this conversation as resolved.
Show resolved Hide resolved
}

// GetUserRepositories returns a list of repositories of given user.
Expand Down
1 change: 1 addition & 0 deletions modules/context/org.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ func HandleOrgAssignment(ctx *Context, args ...bool) {
ctx.Data["IsOrganizationOwner"] = ctx.Org.IsOwner
ctx.Data["IsOrganizationMember"] = ctx.Org.IsMember
ctx.Data["IsPackageEnabled"] = setting.Packages.Enabled
ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled
ctx.Data["IsPublicMember"] = func(uid int64) bool {
is, _ := organization.IsPublicMembership(ctx.Org.Organization.ID, uid)
return is
Expand Down
8 changes: 8 additions & 0 deletions options/locale/locale_en-US.ini
Original file line number Diff line number Diff line change
Expand Up @@ -268,8 +268,11 @@ users = Users
organizations = Organizations
search = Search
code = Code
search.type.tooltip = Search type
search.fuzzy = Fuzzy
search.fuzzy.tooltip = Include results that also matches the search term closely
search.match = Match
search.match.tooltip = Include only results that matches the exact search term
code_search_unavailable = Currently code search is not available. Please contact your site administrator.
repo_no_results = No matching repositories found.
user_no_results = No matching users found.
Expand Down Expand Up @@ -507,6 +510,7 @@ activity = Public Activity
followers = Followers
starred = Starred Repositories
watched = Watched Repositories
code = Code
projects = Projects
following = Following
follow = Follow
Expand Down Expand Up @@ -1763,8 +1767,11 @@ activity.git_stats_deletion_n = %d deletions

search = Search
search.search_repo = Search repository
search.type.tooltip = Search type
search.fuzzy = Fuzzy
search.fuzzy.tooltip = Include results that also matches the search term closely
search.match = Match
search.match.tooltip = Include only results that matches the exact search term
search.results = Search results for "%s" in <a href="%s">%s</a>
search.code_no_results = No source code matching your search term found.
search.code_search_unavailable = Currently code search is not available. Please contact your site administrator.
Expand Down Expand Up @@ -2310,6 +2317,7 @@ create_org = Create Organization
repo_updated = Updated
people = People
teams = Teams
code = Code
lafriks marked this conversation as resolved.
Show resolved Hide resolved
lower_members = members
lower_repositories = repositories
create_new_team = New Team
Expand Down
125 changes: 65 additions & 60 deletions routers/web/explore/code.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,86 +34,91 @@ func Code(ctx *context.Context) {

language := ctx.FormTrim("l")
keyword := ctx.FormTrim("q")

queryType := ctx.FormTrim("t")
isMatch := queryType == "match"

ctx.Data["Keyword"] = keyword
ctx.Data["Language"] = language
ctx.Data["queryType"] = queryType
ctx.Data["PageIsViewCode"] = true

if keyword == "" {
ctx.HTML(http.StatusOK, tplExploreCode)
return
}

page := ctx.FormInt("page")
if page <= 0 {
page = 1
}

queryType := ctx.FormTrim("t")
isMatch := queryType == "match"
var (
repoIDs []int64
err error
isAdmin bool
)
if ctx.Doer != nil {
isAdmin = ctx.Doer.IsAdmin
}

if keyword != "" {
var (
repoIDs []int64
err error
isAdmin bool
)
if ctx.Doer != nil {
isAdmin = ctx.Doer.IsAdmin
// guest user or non-admin user
if ctx.Doer == nil || !isAdmin {
repoIDs, err = repo_model.FindUserCodeAccessibleRepoIDs(ctx, ctx.Doer)
if err != nil {
ctx.ServerError("FindUserCodeAccessibleRepoIDs", err)
return
}
}

// guest user or non-admin user
if ctx.Doer == nil || !isAdmin {
repoIDs, err = repo_model.FindUserCodeAccessibleRepoIDs(ctx.Doer)
if err != nil {
var (
total int
searchResults []*code_indexer.Result
searchResultLanguages []*code_indexer.SearchResultLanguages
)

if (len(repoIDs) > 0) || isAdmin {
total, searchResults, searchResultLanguages, err = code_indexer.PerformSearch(ctx, repoIDs, language, keyword, page, setting.UI.RepoSearchPagingNum, isMatch)
if err != nil {
if code_indexer.IsAvailable() {
ctx.ServerError("SearchResults", err)
return
}
ctx.Data["CodeIndexerUnavailable"] = true
} else {
ctx.Data["CodeIndexerUnavailable"] = !code_indexer.IsAvailable()
}

var (
total int
searchResults []*code_indexer.Result
searchResultLanguages []*code_indexer.SearchResultLanguages
)

if (len(repoIDs) > 0) || isAdmin {
total, searchResults, searchResultLanguages, err = code_indexer.PerformSearch(ctx, repoIDs, language, keyword, page, setting.UI.RepoSearchPagingNum, isMatch)
if err != nil {
if code_indexer.IsAvailable() {
ctx.ServerError("SearchResults", err)
return
loadRepoIDs := make([]int64, 0, len(searchResults))
for _, result := range searchResults {
var find bool
for _, id := range loadRepoIDs {
if id == result.RepoID {
find = true
break
}
ctx.Data["CodeIndexerUnavailable"] = true
} else {
ctx.Data["CodeIndexerUnavailable"] = !code_indexer.IsAvailable()
}

loadRepoIDs := make([]int64, 0, len(searchResults))
for _, result := range searchResults {
var find bool
for _, id := range loadRepoIDs {
if id == result.RepoID {
find = true
break
}
}
if !find {
loadRepoIDs = append(loadRepoIDs, result.RepoID)
}
}

repoMaps, err := repo_model.GetRepositoriesMapByIDs(loadRepoIDs)
if err != nil {
ctx.ServerError("SearchResults", err)
return
if !find {
loadRepoIDs = append(loadRepoIDs, result.RepoID)
}
}

ctx.Data["RepoMaps"] = repoMaps
repoMaps, err := repo_model.GetRepositoriesMapByIDs(loadRepoIDs)
if err != nil {
ctx.ServerError("GetRepositoriesMapByIDs", err)
return
}

ctx.Data["Keyword"] = keyword
ctx.Data["Language"] = language
ctx.Data["queryType"] = queryType
ctx.Data["SearchResults"] = searchResults
ctx.Data["SearchResultLanguages"] = searchResultLanguages
ctx.Data["PageIsViewCode"] = true

pager := context.NewPagination(total, setting.UI.RepoSearchPagingNum, page, 5)
pager.SetDefaultParams(ctx)
pager.AddParam(ctx, "l", "Language")
ctx.Data["Page"] = pager
ctx.Data["RepoMaps"] = repoMaps
}

ctx.Data["SearchResults"] = searchResults
ctx.Data["SearchResultLanguages"] = searchResultLanguages

pager := context.NewPagination(total, setting.UI.RepoSearchPagingNum, page, 5)
pager.SetDefaultParams(ctx)
pager.AddParam(ctx, "l", "Language")
ctx.Data["Page"] = pager

ctx.HTML(http.StatusOK, tplExploreCode)
}
22 changes: 16 additions & 6 deletions routers/web/repo/search.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,27 @@ func Search(ctx *context.Context) {
ctx.Redirect(ctx.Repo.RepoLink)
return
}

language := ctx.FormTrim("l")
keyword := ctx.FormTrim("q")

queryType := ctx.FormTrim("t")
isMatch := queryType == "match"

ctx.Data["Keyword"] = keyword
ctx.Data["Language"] = language
ctx.Data["queryType"] = queryType
ctx.Data["PageIsViewCode"] = true

if keyword == "" {
ctx.HTML(http.StatusOK, tplSearch)
return
}

page := ctx.FormInt("page")
if page <= 0 {
page = 1
}
queryType := ctx.FormTrim("t")
isMatch := queryType == "match"

total, searchResults, searchResultLanguages, err := code_indexer.PerformSearch(ctx, []int64{ctx.Repo.Repository.ID},
language, keyword, page, setting.UI.RepoSearchPagingNum, isMatch)
Expand All @@ -41,13 +54,10 @@ func Search(ctx *context.Context) {
} else {
ctx.Data["CodeIndexerUnavailable"] = !code_indexer.IsAvailable()
}
ctx.Data["Keyword"] = keyword
ctx.Data["Language"] = language
ctx.Data["queryType"] = queryType

ctx.Data["SourcePath"] = ctx.Repo.Repository.HTMLURL()
ctx.Data["SearchResults"] = searchResults
ctx.Data["SearchResultLanguages"] = searchResultLanguages
ctx.Data["PageIsViewCode"] = true

pager := context.NewPagination(total, setting.UI.RepoSearchPagingNum, page, 5)
pager.SetDefaultParams(ctx)
Expand Down
Loading