-
-
Notifications
You must be signed in to change notification settings - Fork 5.4k
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 search mode option to /api/repo/search #2756
Add search mode option to /api/repo/search #2756
Conversation
models/repo_list.go
Outdated
var onlyOwnersRepo = opts.SearchMode == SearchModeFork || opts.SearchMode == SearchModeSource | ||
|
||
if onlyOwnersRepo && opts.OwnerID <= 0 { | ||
return nil, 0, nil |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this result in error if search params are wrong (from UI there should not be such way to get there and from api you need to know that you are calling it wrong)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's question... Params are not wrong, only combination of some parameteres can result in empty result. As I know what combinations will return empty array of repositories I included these 2 tests at start to avoid unnecesary and slow db search.
models/repo_list.go
Outdated
} | ||
|
||
if opts.SearchMode == SearchModeCollaborative && opts.OwnerID > 0 && !opts.Collaborate && !opts.AllPublic { | ||
return nil, 0, nil |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here
Codecov Report
@@ Coverage Diff @@
## master #2756 +/- ##
=========================================
+ Coverage 27.18% 27.2% +0.01%
=========================================
Files 88 88
Lines 17367 17374 +7
=========================================
+ Hits 4721 4726 +5
- Misses 11961 11962 +1
- Partials 685 686 +1
Continue to review full report at Codecov.
|
models/repo_list.go
Outdated
// SearchModeSource source mode | ||
SearchModeSource = "SOURCE" | ||
// SearchModeCollaborative collaborative mode | ||
SearchModeCollaborative = "COLLABORATIVE" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this approach has some disadvantages:
- What if I want to search for all non-mirror repos (both forks and non-forks)? Or all collaborative repos that are also forks? With the current set of search modes, I can't.
- If I use
SearchModeCollaborative
, I must setCollaborate=true
otherwise I won't get any results. If I want collaborative repos, I shouldn't have to say so twice. Ideally, different parameters would not "interfere" with each other in this way.
I propose the following:
// None -> include collaborative AND non-collaborative
// True -> include just collaborative
// False -> incude just non-collaborative
Collaborate util.OptionalBool
// None -> include forks AND non-forks
// True -> include just forks
// False -> include just non-forks
Fork util.OptionalBool
// None -> include mirrors AND non-mirrors
// True -> include just mirrors
// False -> include just non-mirrors
Mirror util.OptionalBool
This allows the caller to specify any combination of conditions, and prevents weird interactions between different parameters.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Your proposition is good and I want to implement this kind of repository search in the future (eg v2 api). But this PR has different purpose and SearchMode
has different meaning. It should mimic behaviour and rules used in repository search on dashboard page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ethantkoenig I think I've over complicated it and you can be right... There is simpler/better solution to achieve what I wanted. I'll be thinking about it.
6f5668c
to
fbca00a
Compare
@ethantkoenig Changed internal implementation as you suggested. Now you can search whatever you want. External behaviour (api) is unchanged from what was expected. @lafriks No more checks at start of function as they are no longer necessary. Updated PR description. |
@@ -37,6 +37,7 @@ | |||
num_repos: 0 | |||
num_members: 1 | |||
unit_types: '[1,2,3,4,5,6,7]' | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: please remove
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was missing 1 empty line, now it is consistent.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are right, my mistake
models/repo_list.go
Outdated
} | ||
|
||
if opts.Fork == util.OptionalBoolTrue && opts.Mirror == util.OptionalBoolTrue { | ||
cond = cond.And(builder.Or(forkCond, mirrorCond)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why treat this as a special case? If opts.Fork
and opts.Mirror
are true, then caller is asking for repos that are both a fork AND a mirror, not repos that are a fork OR a mirror.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think repository can't be fork and mirror at the same time.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe you are right that repos can't be a fork and a mirror. Nonetheless, if opts.Fork
and opts.Mirror
are true, then the caller is asking for repos that are both a fork AND a mirror, and the function should return what the user is asking for (which in this case will be the empty list).
The reason that I'm opposed to making a special case here is that (IMO) opts.Fork
and opts.Mirror
should be independent of each other. Setting opts.Fork
to true should mean that the function will only return forks, regardless of what opts.Mirror
is (and vice versa). Making special cases like "Only forks will be returned if opts.Forks
is true, unless opts.Mirror
is also true, in which case non-fork mirrors will also be returned" introduces unnecessary complexity and opportunities for bugs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can change it, but with this you can do more. Using and
operator has no viable use case, but if you use or
, you can search for repositories that are fork
or mirror
or fork || mirror
or not fork && not mirror
. I don't see any opportunities for bugs here. You should know what you are doing If you ask for something. Same as you use private
you are asking not only private repositories, options are not (or in some cases) exclusive.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ethantkoenig Changed as you wanted.
models/repo_list_test.go
Outdated
}) | ||
|
||
assert.NoError(t, err) | ||
assert.Equal(t, int64(3), count) | ||
assert.Len(t, repos, 3) | ||
|
||
// Test non existing owner | ||
repos, count, err = SearchRepositoryByName(&SearchRepoOptions{OwnerID: int64(99999)}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: use NonexistentID
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, got it...
routers/api/v1/repo/repo.go
Outdated
// searchMode is repository filtering mode identifier | ||
type searchMode int | ||
|
||
const ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't mean to be difficult, but adding a enum just for this one function seems like overkill. From what I can tell, the enum is used in three places:
- In
validateSearchInput()
to check that the user provided a valid mode - In
validateSearchInput()
to check that the user provided a uid for certain modes - In assigning
opts.Collaborate
Could we do the following?
- Add a
default
case to theswitch modeQuery { ...
to handle the case of a user providing an invalid mode - Add check to the
case "source"
andcase "fork"
cases to handle the case of a missing uid- It is unclear to me why such a check is necessary in the first place (what if I want to search for all non-fork repositories, not just those owned by a particular user), but that's another story
- Assign
opts.Collaborate
inside theswitch modeQuery { ...
. IfrepoOwner
turns out to be an organization, we can setopts.Collaborate
to false then
I believe these changes would make the code a lot simpler.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are right, I was looking at it only from user perspective, but it can be more general.
2e5b6b3
to
7e5a718
Compare
@ethantkoenig Done. I've changed api to be more general as you suggested and added new |
2dadb70
to
7d1532b
Compare
LGTM |
@ethantkoenig need your approval |
LGTM |
Make LG-TM work |
Oh, come on... @Morlinest can you please look why test failed? |
9971b5c
to
e7917b0
Compare
@lafriks Sure. Should be resolved now, Unit tests and integration tests on pgsql passed locally. |
@Morlinest
|
test-pgsql and test-mysql run successfully also on drone but |
@Morlinest it could be because of added unit tests that were merged recently so with your added new users something returns more records that test expects |
@lafriks This is weird. I've rebased my PR on master, fixed tests, then run both tests - unit and integration tests ( |
e7917b0
to
2cf2561
Compare
@lafriks Passed after another force push. I don't understand what happened in drone (it had to download bad commit). |
* Add repo type option to /api/repo/search * Add tests and fix result of collaborative filter in specific condition * Fix/optimize search & tests * Improve integration tests * Fix lint errors * Fix unit tests * Change and improve internal implementation of repo search * Use NonexistentID * Make search api more general * Change mirror and fork search behaviour * Fix tests & typo in comment
Replacement of #2326 (can't be reopen). Implements #2321.
all
= default,source
,fork
,mirror
andcollaborative
) with same rules as in dashboard. Every repository type / search mode is related to provided owner ID.SearchRepositoryByName
fork
/mirror
repositories or bothcollaborative
repositoriescollaborative
repositories by default (every call to function was fixed to behave same as before change)Files related to changed behaviour
(:3 files changed, 71 insertions(+), 8 deletions(-)
)models/repo_list.go
routers/api/v1/repo/repo.go
public/swagger.v1.json
collaborative
option changeOther changed files
(+353, -55 lines)are only for tests.This change is esential for implementing #2312 (this PR will reopen #2343)