Skip to content

Commit 7df326e

Browse files
authored
Merge pull request #1315 from sahansera/refactor-search-forks
Refactor GHContentSearchBuilder to allow a Fork type
2 parents 3069134 + 4828993 commit 7df326e

File tree

12 files changed

+4839
-17
lines changed

12 files changed

+4839
-17
lines changed

src/main/java/org/kohsuke/github/GHContentSearchBuilder.java

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,23 @@ public class GHContentSearchBuilder extends GHSearchBuilder<GHContent> {
1212
}
1313

1414
/**
15-
* Search terms.
15+
* {@inheritDoc}
1616
*/
17+
@Override
1718
public GHContentSearchBuilder q(String term) {
1819
super.q(term);
1920
return this;
2021
}
2122

23+
/**
24+
* {@inheritDoc}
25+
*/
26+
@Override
27+
GHContentSearchBuilder q(String qualifier, String value) {
28+
super.q(qualifier, value);
29+
return this;
30+
}
31+
2232
/**
2333
* In gh content search builder.
2434
*
@@ -47,9 +57,27 @@ public GHContentSearchBuilder language(String v) {
4757
* @param v
4858
* the v
4959
* @return the gh content search builder
60+
* @deprecated use {@link #fork(GHFork)}.
5061
*/
62+
@Deprecated
5163
public GHContentSearchBuilder fork(String v) {
52-
return q("fork:" + v);
64+
return q("fork", v);
65+
}
66+
67+
/**
68+
* Fork gh content search builder.
69+
*
70+
* @param fork
71+
* search mode for forks
72+
*
73+
* @return the gh content search builder
74+
*
75+
* @see <a href=
76+
* "https://docs.github.com/en/github/searching-for-information-on-github/searching-on-github/searching-in-forks">Searching
77+
* in forks</a>
78+
*/
79+
public GHContentSearchBuilder fork(GHFork fork) {
80+
return q("fork", fork.toString());
5381
}
5482

5583
/**
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package org.kohsuke.github;
2+
3+
/**
4+
* The enum for Fork search mode
5+
*/
6+
public enum GHFork {
7+
8+
/**
9+
* Search in the parent repository and in forks with more stars than the parent repository.
10+
*
11+
* Forks with the same or fewer stars than the parent repository are still ignored.
12+
*/
13+
PARENT_AND_FORKS("true"),
14+
15+
/**
16+
* Search only in forks with more stars than the parent repository.
17+
*
18+
* The parent repository is ignored. If no forks have more stars than the parent, no results will be returned.
19+
*/
20+
FORKS_ONLY("only"),
21+
22+
/**
23+
* (Default) Search only the parent repository.
24+
*
25+
* Forks are ignored.
26+
*/
27+
PARENT_ONLY("");
28+
29+
private String filterMode;
30+
GHFork(final String mode) {
31+
this.filterMode = mode;
32+
}
33+
34+
@Override
35+
public String toString() {
36+
return filterMode;
37+
}
38+
}

src/main/java/org/kohsuke/github/GHRepositorySearchBuilder.java

Lines changed: 50 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,23 @@ public class GHRepositorySearchBuilder extends GHSearchBuilder<GHRepository> {
1212
}
1313

1414
/**
15-
* Search terms.
15+
* {@inheritDoc}
1616
*/
17+
@Override
1718
public GHRepositorySearchBuilder q(String term) {
1819
super.q(term);
1920
return this;
2021
}
2122

23+
/**
24+
* {@inheritDoc}
25+
*/
26+
@Override
27+
GHRepositorySearchBuilder q(String qualifier, String value) {
28+
super.q(qualifier, value);
29+
return this;
30+
}
31+
2232
/**
2333
* In gh repository search builder.
2434
*
@@ -47,9 +57,11 @@ public GHRepositorySearchBuilder size(String v) {
4757
* @param v
4858
* the v
4959
* @return the gh repository search builder
60+
* @deprecated use {@link #fork(GHFork)} instead.
5061
*/
62+
@Deprecated
5163
public GHRepositorySearchBuilder forks(String v) {
52-
return q("forks:" + v);
64+
return q("fork", v);
5365
}
5466

5567
/**
@@ -74,15 +86,39 @@ public GHRepositorySearchBuilder forks(String v) {
7486
* @see <a href=
7587
* "https://docs.github.com/en/github/searching-for-information-on-github/searching-on-github/searching-in-forks">Searching
7688
* in forks</a>
77-
*
89+
* @deprecated use {@link #fork(GHFork)} instead.
7890
*/
91+
@Deprecated
7992
public GHRepositorySearchBuilder fork(Fork fork) {
80-
if (Fork.PARENT_ONLY.equals(fork)) {
81-
this.terms.removeIf(term -> term.contains("fork:"));
82-
return this;
83-
}
93+
return q("fork", fork.toString());
94+
}
8495

85-
return q("fork:" + fork);
96+
/**
97+
* Searching in forks
98+
*
99+
* The default search mode is {@link Fork#PARENT_ONLY}. In that mode, forks are not included in search results.
100+
*
101+
* <p>
102+
* Passing {@link Fork#PARENT_AND_FORKS} or {@link Fork#FORKS_ONLY} will show results from forks, but only if they
103+
* have more stars than the parent repository.
104+
*
105+
* <p>
106+
* IMPORTANT: Regardless of this setting, no search results will ever be returned for forks with equal or fewer
107+
* stars than the parent repository. Forks with less stars than the parent repository are not included in the index
108+
* for code searching.
109+
*
110+
* @param fork
111+
* search mode for forks
112+
*
113+
* @return the gh repository search builder
114+
*
115+
* @see <a href=
116+
* "https://docs.github.com/en/github/searching-for-information-on-github/searching-on-github/searching-in-forks">Searching
117+
* in forks</a>
118+
*
119+
*/
120+
public GHRepositorySearchBuilder fork(GHFork fork) {
121+
return q("fork", fork.toString());
86122
}
87123

88124
/**
@@ -217,8 +253,11 @@ public enum Sort {
217253
}
218254

219255
/**
220-
* The enum for Fork search mode
256+
* The enum for Fork search mode.
257+
*
258+
* @deprecated Kept for backward compatibility. Use {@link GHFork} instead.
221259
*/
260+
@Deprecated
222261
public enum Fork {
223262

224263
/**
@@ -243,10 +282,11 @@ public enum Fork {
243282
PARENT_ONLY("");
244283

245284
private String filterMode;
246-
Fork(String mode) {
285+
Fork(final String mode) {
247286
this.filterMode = mode;
248287
}
249288

289+
@Override
250290
public String toString() {
251291
return filterMode;
252292
}

src/main/java/org/kohsuke/github/GHSearchBuilder.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
import java.util.ArrayList;
66
import java.util.List;
77

8+
import javax.annotation.CheckForNull;
9+
import javax.annotation.Nonnull;
10+
811
/**
912
* Base class for various search builders.
1013
*
@@ -39,6 +42,30 @@ public GHQueryBuilder<T> q(String term) {
3942
return this;
4043
}
4144

45+
/**
46+
* Add a search term with qualifier.
47+
*
48+
* If {@code value} is empty or {@code null}, all terms with the current qualifier will be removed.
49+
*
50+
* @param qualifier
51+
* the qualifier for this term
52+
* @param value
53+
* the value for this term. If empty or null, all terms with the current qualifier will be removed.
54+
* @return the gh query builder
55+
*/
56+
GHQueryBuilder<T> q(@Nonnull final String qualifier, @CheckForNull final String value) {
57+
if (StringUtils.isEmpty(qualifier)) {
58+
throw new IllegalArgumentException("qualifier cannot be null or empty");
59+
}
60+
if (StringUtils.isEmpty(value)) {
61+
final String removeQualifier = qualifier + ":";
62+
terms.removeIf(term -> term.startsWith(removeQualifier));
63+
} else {
64+
terms.add(qualifier + ":" + value);
65+
}
66+
return this;
67+
}
68+
4269
/**
4370
* Performs the search.
4471
*/

src/test/java/org/kohsuke/github/GHRepositoryTest.java

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -424,7 +424,7 @@ public void searchAllPublicAndForkedRepos() throws IOException {
424424
PagedSearchIterable<GHRepository> list = gitHub.searchRepositories()
425425
.user("t0m4uk1991")
426426
.visibility(GHRepository.Visibility.PUBLIC)
427-
.fork(GHRepositorySearchBuilder.Fork.PARENT_AND_FORKS)
427+
.fork(GHFork.PARENT_AND_FORKS)
428428
.list();
429429
List<GHRepository> u = list.toList();
430430
assertThat(u.size(), is(14));
@@ -437,7 +437,7 @@ public void searchForPublicForkedOnlyRepos() throws IOException {
437437
PagedSearchIterable<GHRepository> list = gitHub.searchRepositories()
438438
.user("t0m4uk1991")
439439
.visibility(GHRepository.Visibility.PUBLIC)
440-
.fork(GHRepositorySearchBuilder.Fork.FORKS_ONLY)
440+
.fork(GHFork.FORKS_ONLY)
441441
.list();
442442
List<GHRepository> u = list.toList();
443443
assertThat(u.size(), is(2));
@@ -467,6 +467,22 @@ public void ghRepositorySearchBuilderIgnoresUnknownVisibility() {
467467
@Test
468468
public void ghRepositorySearchBuilderForkDefaultResetForksSearchTerms() {
469469
GHRepositorySearchBuilder ghRepositorySearchBuilder = new GHRepositorySearchBuilder(gitHub);
470+
471+
ghRepositorySearchBuilder = ghRepositorySearchBuilder.fork(GHFork.PARENT_AND_FORKS);
472+
assertThat(ghRepositorySearchBuilder.terms.stream().filter(item -> item.contains("fork:true")).count(), is(1L));
473+
assertThat(ghRepositorySearchBuilder.terms.stream().filter(item -> item.contains("fork:")).count(), is(1L));
474+
475+
ghRepositorySearchBuilder = ghRepositorySearchBuilder.fork(GHFork.FORKS_ONLY);
476+
assertThat(ghRepositorySearchBuilder.terms.stream().filter(item -> item.contains("fork:only")).count(), is(1L));
477+
assertThat(ghRepositorySearchBuilder.terms.stream().filter(item -> item.contains("fork:")).count(), is(2L));
478+
479+
ghRepositorySearchBuilder = ghRepositorySearchBuilder.fork(GHFork.PARENT_ONLY);
480+
assertThat(ghRepositorySearchBuilder.terms.stream().filter(item -> item.contains("fork:")).count(), is(0L));
481+
}
482+
483+
@Test
484+
public void ghRepositorySearchBuilderForkDeprecatedEnum() {
485+
GHRepositorySearchBuilder ghRepositorySearchBuilder = new GHRepositorySearchBuilder(gitHub);
470486
ghRepositorySearchBuilder = ghRepositorySearchBuilder.fork(GHRepositorySearchBuilder.Fork.PARENT_AND_FORKS);
471487
assertThat(ghRepositorySearchBuilder.terms.stream().filter(item -> item.contains("fork:true")).count(), is(1L));
472488
assertThat(ghRepositorySearchBuilder.terms.stream().filter(item -> item.contains("fork:")).count(), is(1L));
@@ -479,6 +495,21 @@ public void ghRepositorySearchBuilderForkDefaultResetForksSearchTerms() {
479495
assertThat(ghRepositorySearchBuilder.terms.stream().filter(item -> item.contains("fork:")).count(), is(0L));
480496
}
481497

498+
@Test
499+
public void ghRepositorySearchBuilderForkDeprecatedString() {
500+
GHRepositorySearchBuilder ghRepositorySearchBuilder = new GHRepositorySearchBuilder(gitHub);
501+
ghRepositorySearchBuilder = ghRepositorySearchBuilder.forks(GHFork.PARENT_AND_FORKS.toString());
502+
assertThat(ghRepositorySearchBuilder.terms.stream().filter(item -> item.contains("fork:true")).count(), is(1L));
503+
assertThat(ghRepositorySearchBuilder.terms.stream().filter(item -> item.contains("fork:")).count(), is(1L));
504+
505+
ghRepositorySearchBuilder = ghRepositorySearchBuilder.forks(GHFork.FORKS_ONLY.toString());
506+
assertThat(ghRepositorySearchBuilder.terms.stream().filter(item -> item.contains("fork:only")).count(), is(1L));
507+
assertThat(ghRepositorySearchBuilder.terms.stream().filter(item -> item.contains("fork:")).count(), is(2L));
508+
509+
ghRepositorySearchBuilder = ghRepositorySearchBuilder.forks(null);
510+
assertThat(ghRepositorySearchBuilder.terms.stream().filter(item -> item.contains("fork:")).count(), is(0L));
511+
}
512+
482513
@Test
483514
public void listCommitCommentsSomeComments() throws IOException {
484515
List<GHCommitComment> commitComments = getRepository()

src/test/java/org/kohsuke/github/GitHubTest.java

Lines changed: 53 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package org.kohsuke.github;
22

33
import com.google.common.collect.Iterables;
4+
import org.junit.Assert;
45
import org.junit.Test;
56
import org.kohsuke.github.example.dataobject.ReadOnlyObjects;
67

@@ -138,20 +139,69 @@ public void searchContent() throws Exception {
138139
assertThat(c3.getPath(), not(equalTo(c2.getPath())));
139140
assertThat(r3.getTotalCount(), equalTo(r2.getTotalCount()));
140141

141-
PagedSearchIterable<GHContent> r4 = gitHub.searchContent()
142+
GHContentSearchBuilder searchBuilder = gitHub.searchContent()
142143
.q("addClass")
143144
.in("file")
144145
.language("js")
145146
.repo("jquery/jquery")
146147
.sort(GHContentSearchBuilder.Sort.INDEXED)
147-
.order(GHDirection.DESC)
148-
.list();
148+
.order(GHDirection.DESC);
149+
150+
PagedSearchIterable<GHContent> r4 = searchBuilder.list();
149151

150152
GHContent c4 = r4.iterator().next();
151153
assertThat(c4.getPath(), not(equalTo(c2.getPath())));
152154
assertThat(c4.getPath(), not(equalTo(c3.getPath())));
153155
assertThat(r4.getTotalCount(), equalTo(r2.getTotalCount()));
154156

157+
// Verify qualifier not allowed to be empty
158+
IllegalArgumentException e = Assert.assertThrows(IllegalArgumentException.class,
159+
() -> searchBuilder.q("", "not valid"));
160+
assertThat(e.getMessage(), equalTo("qualifier cannot be null or empty"));
161+
}
162+
163+
@Test
164+
public void searchContentWithForks() {
165+
final PagedSearchIterable<GHContent> results = gitHub.searchContent()
166+
.q("addClass")
167+
.language("js")
168+
.sort(GHContentSearchBuilder.Sort.INDEXED)
169+
.order(GHDirection.DESC)
170+
.fork(GHFork.PARENT_ONLY)
171+
.list();
172+
173+
final PagedSearchIterable<GHContent> resultsWithForks = gitHub.searchContent()
174+
.q("addClass")
175+
.language("js")
176+
.sort(GHContentSearchBuilder.Sort.INDEXED)
177+
.order(GHDirection.DESC)
178+
.fork(GHFork.PARENT_AND_FORKS)
179+
.list();
180+
181+
assertThat(results.getTotalCount(), lessThan(resultsWithForks.getTotalCount()));
182+
183+
// Do not record these.
184+
// This will verify that the queries for the deprecated path are identical to the ones above.
185+
if (!mockGitHub.isTakeSnapshot()) {
186+
final PagedSearchIterable<GHContent> resultsDeprecated = gitHub.searchContent()
187+
.q("addClass")
188+
.language("js")
189+
.sort(GHContentSearchBuilder.Sort.INDEXED)
190+
.order(GHDirection.DESC)
191+
.fork(GHFork.PARENT_ONLY.toString())
192+
.list();
193+
194+
final PagedSearchIterable<GHContent> resultsWithForksDeprecated = gitHub.searchContent()
195+
.q("addClass")
196+
.language("js")
197+
.sort(GHContentSearchBuilder.Sort.INDEXED)
198+
.order(GHDirection.DESC)
199+
.fork(GHFork.PARENT_AND_FORKS.toString())
200+
.list();
201+
202+
assertThat(resultsDeprecated.getTotalCount(), equalTo(results.getTotalCount()));
203+
assertThat(resultsWithForksDeprecated.getTotalCount(), equalTo(resultsWithForks.getTotalCount()));
204+
}
155205
}
156206

157207
@Test

0 commit comments

Comments
 (0)