Skip to content

Commit 94df5fc

Browse files
authored
Merge pull request #923 from bitwiseman/feature/is-template
Added GHRepository.isTemplate() method
2 parents ff4324a + 906238a commit 94df5fc

24 files changed

+667
-184
lines changed

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

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -154,10 +154,7 @@ public List<GHRepository> next() {
154154
*/
155155
public GHRepository getRepository(String name) throws IOException {
156156
try {
157-
return root.createRequest()
158-
.withUrlPath("/repos/" + login + '/' + name)
159-
.fetch(GHRepository.class)
160-
.wrap(root);
157+
return GHRepository.read(root, login, name);
161158
} catch (FileNotFoundException e) {
162159
return null;
163160
}

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

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -80,10 +80,8 @@ public GHObject getOwner() throws IOException {
8080
} else if (owner_url.contains("/users/")) {
8181
owner = root.createRequest().withUrlPath(getOwnerUrl().getPath()).fetch(GHUser.class).wrapUp(root);
8282
} else if (owner_url.contains("/repos/")) {
83-
owner = root.createRequest()
84-
.withUrlPath(getOwnerUrl().getPath())
85-
.fetch(GHRepository.class)
86-
.wrap(root);
83+
String[] pathElements = getOwnerUrl().getPath().split("/");
84+
owner = GHRepository.read(root, pathElements[1], pathElements[2]);
8785
}
8886
} catch (FileNotFoundException e) {
8987
return null;

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

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,12 @@ public class GHRepository extends GHObject {
111111

112112
private GHRepository source, parent;
113113

114+
private Boolean isTemplate;
115+
116+
static GHRepository read(GitHub root, String owner, String name) throws IOException {
117+
return root.createRequest().withUrlPath("/repos/" + owner + '/' + name).fetch(GHRepository.class).wrap(root);
118+
}
119+
114120
/**
115121
* Create deployment gh deployment builder.
116122
*
@@ -692,6 +698,28 @@ public boolean isPrivate() {
692698
return _private;
693699
}
694700

701+
/**
702+
* Is template boolean.
703+
*
704+
* @return the boolean
705+
*/
706+
@Deprecated
707+
@Preview
708+
public boolean isTemplate() {
709+
// isTemplate is still in preview, we do not want to retrieve it unless needed.
710+
if (isTemplate == null) {
711+
try {
712+
populate();
713+
} catch (IOException e) {
714+
// Convert this to a runtime exception to avoid messy method signature
715+
throw new GHException("Could not populate the template setting of the repository", e);
716+
}
717+
// if this somehow is not populated, set it to false;
718+
isTemplate = Boolean.TRUE.equals(isTemplate);
719+
}
720+
return isTemplate;
721+
}
722+
695723
/**
696724
* Has downloads boolean.
697725
*
@@ -2855,10 +2883,10 @@ void populate() throws IOException {
28552883
// There is bug in Push event payloads that returns the wrong url.
28562884
// All other occurrences of "url" take the form "https://api.github.com/...".
28572885
// For Push event repository records, they take the form "https://github.com/{fullName}".
2858-
root.createRequest().setRawUrlPath(url.toString()).fetchInto(this).wrap(root);
2886+
root.createRequest().withPreview(BAPTISE).setRawUrlPath(url.toString()).fetchInto(this).wrap(root);
28592887
} catch (HttpException e) {
28602888
if (e.getCause() instanceof JsonParseException) {
2861-
root.createRequest().withUrlPath("/repos/" + full_name).fetchInto(this).wrap(root);
2889+
root.createRequest().withPreview(BAPTISE).withUrlPath("/repos/" + full_name).fetchInto(this).wrap(root);
28622890
} else {
28632891
throw e;
28642892
}

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

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -546,9 +546,7 @@ public GHRepository getRepository(String name) throws IOException {
546546
if (tokens.length < 2) {
547547
throw new IllegalArgumentException("Repository name must be in format owner/repo");
548548
}
549-
return createRequest().withUrlPath("/repos/" + tokens[0] + '/' + tokens[1])
550-
.fetch(GHRepository.class)
551-
.wrap(this);
549+
return GHRepository.read(this, tokens[0], tokens[1]);
552550
}
553551

554552
/**

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -405,7 +405,7 @@ public <T> GitHubResponse<T> sendRequest(GitHubRequest request, @CheckForNull Gi
405405
// Setting "Cache-Control" to "no-cache" stops the cache from supplying
406406
// "If-Modified-Since" or "If-None-Match" values.
407407
// This makes GitHub give us current data (not incorrectly cached data)
408-
request = request.toBuilder().withHeader("Cache-Control", "no-cache").build();
408+
request = request.toBuilder().setHeader("Cache-Control", "no-cache").build();
409409
continue;
410410
}
411411
if (!(isRateLimitResponse(responseInfo) || isAbuseLimitResponse(responseInfo))) {

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

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -384,9 +384,11 @@ public B withApiUrl(String url) {
384384
* the name
385385
* @param value
386386
* the value
387+
* @return the request builder
387388
*/
388-
public void setHeader(String name, String value) {
389+
public B setHeader(String name, String value) {
389390
headers.put(name, value);
391+
return (B) this;
390392
}
391393

392394
/**
@@ -399,8 +401,11 @@ public void setHeader(String name, String value) {
399401
* @return the request builder
400402
*/
401403
public B withHeader(String name, String value) {
402-
setHeader(name, value);
403-
return (B) this;
404+
String oldValue = headers.get(name);
405+
if (!StringUtils.isBlank(oldValue)) {
406+
value = oldValue + ", " + value;
407+
}
408+
return setHeader(name, value);
404409
}
405410

406411
/**

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

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,14 @@ class Previews {
1515
*/
1616
static final String ANTIOPE = "application/vnd.github.antiope-preview+json";
1717

18+
/**
19+
* Create repository from template repository
20+
*
21+
* @see <a href="https://developer.github.com/v3/previews/#create-and-use-repository-templates">GitHub API
22+
* Previews</a>
23+
*/
24+
static final String BAPTISE = "application/vnd.github.baptiste-preview+json";
25+
1826
/**
1927
* Commit Search
2028
*
@@ -58,6 +66,14 @@ class Previews {
5866
*/
5967
static final String MERCY = "application/vnd.github.mercy-preview+json";
6068

69+
/**
70+
* New visibility parameter for the Repositories API
71+
*
72+
* @see <a href="https://developer.github.com/v3/previews/#new-visibility-parameter-for-the-repositories-api">GitHub
73+
* API Previews</a>
74+
*/
75+
static final String NEBULA = "application/vnd.github.nebula-preview+json";
76+
6177
/**
6278
* Draft pull requests
6379
*
@@ -79,11 +95,4 @@ class Previews {
7995
*/
8096
static final String ZZZAX = "application/vnd.github.zzzax-preview+json";
8197

82-
/**
83-
* Create repository from template repository
84-
*
85-
* @see <a href="https://developer.github.com/v3/previews/#create-and-use-repository-templates">GitHub API
86-
* Previews</a>
87-
*/
88-
static final String BAPTISE = "application/vnd.github.baptiste-preview+json";
8998
}

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

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
import java.io.IOException;
1010
import java.util.List;
1111

12+
import static org.hamcrest.Matchers.*;
13+
1214
public class GHOrganizationTest extends AbstractGitHubWireMockTest {
1315

1416
public static final String GITHUB_API_TEST = "github-api-test";
@@ -59,18 +61,39 @@ public void testCreateRepositoryWithAutoInitialization() throws IOException {
5961

6062
@Test
6163
public void testCreateRepositoryWithParameterIsTemplate() throws IOException {
62-
cleanupRepository(GITHUB_API_TEST_ORG + '/' + GITHUB_API_TEST);
64+
cleanupRepository(GITHUB_API_TEST_ORG + '/' + GITHUB_API_TEMPLATE_TEST);
6365

6466
GHOrganization org = gitHub.getOrganization(GITHUB_API_TEST_ORG);
67+
GHTeam team = org.getTeamByName("Core Developers");
68+
69+
int requestCount = mockGitHub.getRequestCount();
6570
GHRepository repository = org.createRepository(GITHUB_API_TEMPLATE_TEST)
6671
.description("a test template repository used to test kohsuke's github-api")
6772
.homepage("http://github-api.kohsuke.org/")
68-
.team(org.getTeamByName("Core Developers"))
73+
.team(team)
6974
.autoInit(true)
7075
.templateRepository(true)
7176
.create();
7277
Assert.assertNotNull(repository);
78+
assertThat(mockGitHub.getRequestCount(), equalTo(requestCount + 1));
79+
7380
Assert.assertNotNull(repository.getReadme());
81+
assertThat(mockGitHub.getRequestCount(), equalTo(requestCount + 2));
82+
83+
// isTemplate() does not call populate() from create
84+
assertThat(repository.isTemplate(), equalTo(true));
85+
assertThat(mockGitHub.getRequestCount(), equalTo(requestCount + 2));
86+
87+
repository = org.getRepository(GITHUB_API_TEMPLATE_TEST);
88+
89+
// first isTemplate() calls populate()
90+
assertThat(repository.isTemplate(), equalTo(true));
91+
assertThat(mockGitHub.getRequestCount(), equalTo(requestCount + 4));
92+
93+
// second isTemplate() does not call populate()
94+
assertThat(repository.isTemplate(), equalTo(true));
95+
assertThat(mockGitHub.getRequestCount(), equalTo(requestCount + 4));
96+
7497
}
7598

7699
@Test
@@ -85,6 +108,7 @@ public void testCreateRepositoryWithTemplate() throws IOException {
85108

86109
Assert.assertNotNull(repository);
87110
Assert.assertNotNull(repository.getReadme());
111+
88112
}
89113

90114
@Test

src/test/resources/org/kohsuke/github/GHEventPayloadTest/wiremock/pushToFork/__files/repos_hub4j-test-org_github-api-2.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@
9393
"url": "https://api.github.com/licenses/mit",
9494
"node_id": "MDc6TGljZW5zZTEz"
9595
},
96+
"is_template": false,
9697
"forks": 0,
9798
"open_issues": 5,
9899
"watchers": 0,

src/test/resources/org/kohsuke/github/GHEventPayloadTest/wiremock/pushToFork/mappings/repos_hub4j-test-org_github-api-2.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"method": "GET",
77
"headers": {
88
"Accept": {
9-
"equalTo": "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2"
9+
"equalTo": "application/vnd.github.baptiste-preview+json"
1010
}
1111
}
1212
},

src/test/resources/org/kohsuke/github/GHOrganizationTest/wiremock/testCreateRepositoryWithParameterIsTemplate/__files/orgs_hub4j-test-org-2.json

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,22 +10,28 @@
1010
"members_url": "https://api.github.com/orgs/hub4j-test-org/members{/member}",
1111
"public_members_url": "https://api.github.com/orgs/hub4j-test-org/public_members{/member}",
1212
"avatar_url": "https://avatars3.githubusercontent.com/u/7544739?v=4",
13-
"description": null,
13+
"description": "Hub4j Test Org Description (this could be null or blank too)",
14+
"name": "Hub4j Test Org Name (this could be null or blank too)",
15+
"company": null,
16+
"blog": "https://hub4j.url.io/could/be/null",
17+
"location": "Hub4j Test Org Location (this could be null or blank too)",
18+
"email": "hub4jtestorgemail@could.be.null.com",
19+
"twitter_username": null,
1420
"is_verified": false,
1521
"has_organization_projects": true,
1622
"has_repository_projects": true,
17-
"public_repos": 9,
23+
"public_repos": 12,
1824
"public_gists": 0,
1925
"followers": 0,
2026
"following": 0,
2127
"html_url": "https://github.com/hub4j-test-org",
2228
"created_at": "2014-05-10T19:39:11Z",
23-
"updated_at": "2015-04-20T00:42:30Z",
29+
"updated_at": "2020-06-04T05:56:10Z",
2430
"type": "Organization",
2531
"total_private_repos": 0,
2632
"owned_private_repos": 0,
2733
"private_gists": 0,
28-
"disk_usage": 132,
34+
"disk_usage": 148,
2935
"collaborators": 0,
3036
"billing_email": "kk@kohsuke.org",
3137
"default_repository_permission": "none",
@@ -34,8 +40,8 @@
3440
"plan": {
3541
"name": "free",
3642
"space": 976562499,
37-
"private_repos": 0,
38-
"filled_seats": 3,
39-
"seats": 0
43+
"private_repos": 10000,
44+
"filled_seats": 18,
45+
"seats": 3
4046
}
4147
}

0 commit comments

Comments
 (0)