Compare commits

...

528 Commits

Author SHA1 Message Date
Liam Newman
d667b2f822 [maven-release-plugin] prepare release github-api-1.101 2019-11-27 10:27:24 -08:00
Liam Newman
d7f511363d Merge pull request #627 from alecharp/fix-cache-control-packagename
Fixed CacheControl package name
2019-11-27 10:14:12 -08:00
Adrien Lecharpentier
39e7c5c3de Fixed CacheControl package name
With okhttp 3, the package name changed. In the okhttp3.OkHttpConnector,
the incorrect class is loaded, creating a ClassNotFoundException at
runtime when okhttp3 only is loaded.
2019-11-27 18:30:06 +01:00
Liam Newman
60acd5c864 Update CHANGELOG.md 2019-11-26 19:08:00 -08:00
Liam Newman
b92cf6fd35 [maven-release-plugin] prepare for next development iteration 2019-11-26 17:53:42 -08:00
Liam Newman
f7d048e0b9 [maven-release-plugin] prepare release github-api-1.100 2019-11-26 17:53:14 -08:00
Liam Newman
b3d79622e6 Fix lifecycle test to not fail during release 2019-11-26 17:46:49 -08:00
Liam Newman
7e7ae79477 Update change log for 1.100 2019-11-26 17:46:49 -08:00
Liam Newman
5910988314 Merge pull request #625 from bitwiseman/bug/content-encode
Fixed GHContent to allow spaces in path
2019-11-25 18:13:38 -08:00
Liam Newman
8c4b1ef74a Fixed GHContent to allow spaces in path
URI path encoding whack-a-mole.  This fix should cover a significant number of cases.

Also, fixed to NOT do URLEncode for URI path.  The encoding is different between path and query.

Fixes #624
2019-11-25 18:06:19 -08:00
Liam Newman
7d4f1941e7 Merge pull request #621 from bitwiseman/lifecycle
Re-enable Lifecycle test
2019-11-21 22:26:48 -08:00
Liam Newman
eedefcdbbb Reformat a few json test files 2019-11-21 22:19:10 -08:00
Liam Newman
bdb5e82abc Make servers only start if the might be needed
If proxying or snapshotting, we start all servers.
Otherwise only start a server if we have mapping files for them.
2019-11-21 22:09:54 -08:00
Liam Newman
ff766a46c8 Enable uploads testing and LifecycleTest
Fixed asset upload url to not hard coded
2019-11-21 17:07:38 -08:00
Liam Newman
0a40dc5939 Merge pull request #620 from siordache-forks/issue#504
fix and unit tests for issue #504
2019-11-20 22:34:02 -08:00
Serban Iordache
71862d76d3 remove '@apiNote' javadoc tag 2019-11-21 00:45:45 +01:00
Serban Iordache
7a35cc3d17 fix and unit tests for issue #504
add new methods for creating tree content
2019-11-21 00:31:36 +01:00
Liam Newman
7a4870c977 Merge pull request #619 from asthinasthi/deprecate-permission
Removed permission field in createTeam. It is deprecated in the API
2019-11-20 09:29:26 -08:00
Matt Farmer
d4d2792498 Deprecated permission field in createTeam & provided alternate method 2019-11-19 17:15:50 -08:00
Liam Newman
a969509283 Merge pull request #616 from bitwiseman/impsort
Cleanup imports
2019-11-18 19:53:07 -08:00
Liam Newman
82fa340c07 Import sorting cleanup 2019-11-18 19:14:24 -08:00
Liam Newman
d44cd4a827 Merge remote-tracking branch 'github-api/master' into impsort 2019-11-18 19:13:27 -08:00
Liam Newman
a8dbe65e30 Move GistTest to GHGistTest 2019-11-18 19:13:10 -08:00
Liam Newman
d2ce7c11ac Merge pull request #615 from alexanderrtaylor/BranchMissing
Branch missing
2019-11-18 19:08:40 -08:00
Liam Newman
d02af5ccb0 Switch property mapper to snake case
Jackson to automatically map property names using known patterns.
GitHub uses snake_case.
2019-11-18 19:05:43 -08:00
Liam Newman
9a5467dcac Re-enable GHBranchProtection test 2019-11-18 19:05:43 -08:00
Liam Newman
2af4f61882 Cleanup imports 2019-11-18 11:35:45 -08:00
Liam Newman
cbd06eef96 Code formatting 2019-11-15 15:51:07 -08:00
Liam Newman
392dc2a040 Merge remote-tracking branch 'github-api/master' into BranchMissing 2019-11-15 15:36:24 -08:00
Liam Newman
da11702f68 Modify formatting to columnize
Turns out I do care about formatting a little.  We have a lot of builders and chained methods.
I think it is easier to follow long chains when lined up veritcally.
2019-11-15 15:18:07 -08:00
Liam Newman
f262bf7cdb Commit default format 2019-11-15 13:49:32 -08:00
Alex Taylor
78ab5ad156 Changed Exception Type
Changed Exception type and added a comment
2019-11-15 14:55:50 -05:00
Alex Taylor
6af796fc3b Adjusted format
Adjusted format according to standard from repo
2019-11-15 14:35:32 -05:00
Liam Newman
c174be37b3 Merge pull request #614 from bitwiseman/task/requester-cleanup
Clean up Requester interface a bit
2019-11-15 08:40:45 -08:00
Alex Taylor
18aa067c44 Merge branch 'master' into BranchMissing 2019-11-15 10:59:15 -05:00
Alex Taylor
8d50b338f4 Added GHBranch creator
Added GHBranch creator and added a test to make sure it works
2019-11-15 10:54:32 -05:00
Liam Newman
37d7cfaaf2 Clean up Requester interface a bit 2019-11-14 18:16:56 -08:00
Liam Newman
d3564a9a4f Merge pull request #613 from bitwiseman/javadoc-warning
Javadoc fail on warning during CI build
2019-11-14 15:53:50 -08:00
Liam Newman
39d6dd9916 Update PULL_REQUEST_TEMPLATE.md 2019-11-14 13:36:33 -08:00
Liam Newman
0152ebf062 Enable failOnWarning for JavaDoc
Continuing to ratchet up some base level code quality
2019-11-14 13:33:33 -08:00
Liam Newman
757b9b2118 Add JavaDocs
Do using IntelliJ JavaDocs plugin. Better to have something than nothing.
2019-11-14 13:24:28 -08:00
Liam Newman
f6a01551fd Make PagedIterableWithConsumer package local for mocking 2019-11-14 13:15:34 -08:00
Liam Newman
1f619f3801 Merge pull request #611 from PauloMigAlmeida/master
Implement Meta endpoint
2019-11-14 13:06:43 -08:00
Liam Newman
fd436cf5b2 Fixes for build failures 2019-11-14 13:01:35 -08:00
Liam Newman
7e05ce38cf Add examples of different ways to create data objects 2019-11-14 12:39:40 -08:00
Liam Newman
7d1e977ffe Make GHMeta fields effectively final 2019-11-14 12:39:04 -08:00
Liam Newman
6c2ce83b45 Make GHMeta fields not externally settable 2019-11-14 10:29:40 -08:00
Liam Newman
d5ba0eebcb Run code formatting 2019-11-14 09:12:28 -08:00
Liam Newman
432585cb75 Merge remote-tracking branch 'github-api/master' into ghmeta 2019-11-14 09:05:20 -08:00
Liam Newman
e41a341ce6 Merge pull request #609 from bitwiseman/task/style
Code style fixes
2019-11-14 08:47:47 -08:00
PauloMigAlmeida
6aad80904a Implement Meta endpoint
Signed-off-by: PauloMigAlmeida <paulo.miguel.almeida.rodenas@gmail.com>
2019-11-14 15:52:43 +13:00
Liam Newman
20e796cef4 Create PULL_REQUEST_TEMPLATE.md 2019-11-13 15:47:55 -08:00
Liam Newman
a3b126282d Remove package comments 2019-11-13 15:20:02 -08:00
Liam Newman
5f597379b5 JavaDoc warning fixes 2019-11-13 14:53:42 -08:00
Liam Newman
9d8460bb81 Enable automatic code formatter with CI validation
This may be controversial but it we're doing it. Having code formatting needs to be consistent
and a non-issue during code review. I'm willing modify the configuration if people see a strong
need, but formatting needs to be present and enforced.
2019-11-13 13:28:23 -08:00
Liam Newman
8943af9840 Cleanup tabs and whitespace 2019-11-13 12:47:19 -08:00
Liam Newman
d23c718036 Merge pull request #603 from madhephaestus/master
Add Functionality of OTP to support user 2fa
2019-11-13 12:43:23 -08:00
Alex Taylor
834c84c9ea Added the test for Issue #607
Added a test so that we can prove when this issue is fixed
2019-11-13 15:07:06 -05:00
Liam Newman
adc436a3f5 Update issue templates 2019-11-13 09:48:25 -08:00
Kevin Harrington
e325bf7771 fixed for the sensitive javadoc parser 2019-11-13 00:38:51 -05:00
Kevin Harrington
feabd07a21 adding javadoc 2019-11-13 00:28:18 -05:00
Kevin Harrington
e138c6fd61 Switch interface to existing Supplier class 2019-11-13 00:26:20 -05:00
Kevin Harrington
d32299fde5 add testing of scopes in assigned token 2019-11-13 00:23:38 -05:00
Kevin Harrington
3d7d780e8f only run test with moc date 2019-11-13 00:19:06 -05:00
Kevin Harrington
9f49854033 Comments for the path of OTP exception 2019-11-13 00:17:57 -05:00
Kevin Harrington
1fe820d463 instructions for reproducing the test data 2019-11-12 18:15:08 -05:00
Kevin Harrington
4a78690fde Remove old function prototype and replace it with the lambda model. 2019-11-12 18:10:05 -05:00
Kevin Harrington
3dcaf5a9de Unit test passing with Mock data 2019-11-12 18:05:39 -05:00
Kevin Harrington
ff788852d6 added the filter to the test to only run with mock data 2019-11-12 17:58:21 -05:00
Kevin Harrington
5ae062719e re-run the data capture with the overloaded function 2019-11-12 17:56:25 -05:00
Kevin Harrington
421c0a11fb Implement @PauloMigAlmeida suggested lambda style OTP workflow 2019-11-12 17:32:24 -05:00
Kevin Harrington
6ae586aeb7 Creating a receiver lambda for the PTM functionality 2019-11-12 17:28:23 -05:00
Liam Newman
7036423084 Merge pull request #595 from bitwiseman/issue/rate-limit
Adjust GHRateLimit to system time instead of depending on synchronization
2019-11-12 13:01:58 -08:00
Kevin Harrington
2f118a9cbe Adding suggested exception from @PauloMigAlmeida
When the OTP code is requested, then the special GHOTPRequiredException
is raised instead of the generic IOException. This differentiates
between an OTP request and a failed password.
2019-11-12 15:44:45 -05:00
Kevin Harrington
2c50255b21 renaming 2019-11-12 15:35:55 -05:00
harrington
8cb7210c46 set the timestamp in the token name to match the test data 2019-11-12 15:01:14 -05:00
harrington
ad0a24ad2f Make sure test is only run with stored mock data 2019-11-12 14:54:38 -05:00
harrington
df6c951830 Unit test passing with OTP data 2019-11-12 14:53:14 -05:00
harrington
5da2caa616 Adding the assume only valid when live 2019-11-12 13:00:51 -05:00
harrington
a3fe95d1e4 clear junk data 2019-11-12 12:58:22 -05:00
Liam Newman
38e61c121b Merge pull request #604 from sullis/jackson-2.10.1
jackson 2.10.1
2019-11-11 14:31:21 -08:00
Liam Newman
03e9623073 Updates based on review feedback
Created GHRateLimit.Record
Add the four rate limit records to GHRateLimit
Moved getLimt(), getRemaining(), and so on to point to core record for ease of use.
Fixed update check for header to not replace existing with older when remaining count is lower.

NOTE: Did not expose records other than core and did not resolve header update behavior to respect non-core records.
2019-11-11 14:29:36 -08:00
Sean C. Sullivan
93a1657e1e jackson 2.10.1 2019-11-10 18:31:29 -05:00
Kevin Harrington
91d67fb72f Tuning the test to pass 2019-11-10 12:13:38 -05:00
Kevin Harrington
d8cc1f885c Properly disabling the test 2019-11-10 11:32:59 -05:00
Kevin Harrington
c1f999d896 Disabling test that can't run on CI 2019-11-10 11:27:45 -05:00
Kevin Harrington
efc4d0f59b Merge branch 'master' of git@github.com:madhephaestus/github-api.git 2019-11-10 11:20:50 -05:00
Kevin Harrington
cf55d670b9 Added test to comply with CONTRIBUTING.md
Test extends AbstractGitHubWireMockTest

Test requires 2fa and the user at the command line as the test is run.
2019-11-10 11:20:32 -05:00
Kevin Harrington
8567c5e6a1 Update src/main/java/org/kohsuke/github/GitHub.java
spelling

Co-Authored-By: Liam Newman <bitwiseman@gmail.com>
2019-11-10 10:26:51 -05:00
Kevin Harrington
331084fefd comments 2019-11-09 16:47:26 -05:00
Kevin Harrington
62bf691ac1 Add Functionality of OTP to github
close #602 by adding an API to request a token using an OTP.
2019-11-09 16:43:25 -05:00
Liam Newman
09b41d4665 Merge pull request #593 from github-api/dependabot/maven/com.squareup.okhttp3-okhttp-4.2.2
Bump okhttp from 3.14.2 to 4.2.2
2019-11-07 17:36:00 -08:00
Liam Newman
71645240e9 Address Spotbugs issues in dependency update 2019-11-07 16:40:59 -08:00
dependabot-preview[bot]
603468823d Bump okhttp from 3.14.2 to 4.2.2
Bumps [okhttp](https://github.com/square/okhttp) from 3.14.2 to 4.2.2.
- [Release notes](https://github.com/square/okhttp/releases)
- [Changelog](https://github.com/square/okhttp/blob/master/CHANGELOG.md)
- [Commits](https://github.com/square/okhttp/compare/parent-3.14.2...parent-4.2.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-11-07 16:18:48 -08:00
Liam Newman
01f464cc69 Add gitter.io chat 2019-11-07 15:47:39 -08:00
Liam Newman
57ac6e982f Updated Last-Modified headers
Introduces #597

This does not appear to be a bug in github-api but in OkHttp 2.7.5
(and/or the Cache implementation in that version).
2019-11-07 14:05:54 -08:00
Liam Newman
319d2d1efe Update cache test Date and Limit values 2019-11-07 13:50:57 -08:00
Liam Newman
37de3a4122 Add tests for server time ahead and behind local time
Sometimes adding tests finds broken product code.  Sometimes it finds broken test environment.
This was the latter.

The wiremock templating returns dates in UTC format not RFC-1123 format.
2019-11-07 13:24:31 -08:00
Liam Newman
bb3a49264d Merge remote-tracking branch 'github-api/master' into issue/rate-limit 2019-11-07 11:38:00 -08:00
Liam Newman
9cecce74fa Merge pull request #594 from martinvanzijl/add-method-to-set-topics
Add method to set repository topics
2019-11-06 21:26:31 -08:00
Liam Newman
f9cf2878ef Tweaks to test 2019-11-06 21:20:55 -08:00
Liam Newman
9c80b7cf54 Various clean up and fixes for GHRateLimit 2019-11-06 20:38:10 -08:00
Liam Newman
1ecad7031f Handle GHRateLimit expiration and server time inconsistency 2019-11-06 17:17:26 -08:00
Martin van Zijl
c85d6107ec Added method to set repository topics. Fixes #546. 2019-11-07 13:41:14 +13:00
Liam Newman
7b7445b601 Clean up GHRateLimit
Improves the way reset date is calculated - uses server date if possible.

Fixes #383
2019-11-06 11:11:53 -08:00
Liam Newman
1ab474673d Lock okhttp3 UrlConnection to working versions, unlock client 2019-11-04 15:15:28 -08:00
Liam Newman
dbf92e7f20 Added changelog 2019-11-04 11:02:11 -08:00
Liam Newman
6c42db2508 Add release version tag 2019-11-04 10:30:08 -08:00
Liam Newman
c9a42178e8 [maven-release-plugin] prepare for next development iteration 2019-11-04 10:09:02 -08:00
Liam Newman
eff48dfe67 [maven-release-plugin] prepare release github-api-1.99 2019-11-04 10:08:55 -08:00
Liam Newman
0c38bdc068 Merge pull request #590 from github-api/dependabot/maven/org.apache.maven.plugins-maven-source-plugin-3.2.0
Bump maven-source-plugin from 3.1.0 to 3.2.0
2019-11-04 09:35:00 -08:00
Liam Newman
b8e1736696 [maven-release-plugin] prepare for next development iteration 2019-11-04 09:16:45 -08:00
Liam Newman
c2f36444d0 [maven-release-plugin] prepare release github-api-1.98 2019-11-04 09:16:39 -08:00
Liam Newman
5dc74f5b4d [maven-release-plugin] prepare for next development iteration 2019-11-04 08:30:58 -08:00
Liam Newman
9694dfe4cc [maven-release-plugin] prepare release github-api-1.97 2019-11-04 08:30:51 -08:00
Liam Newman
734125ea14 [maven-release-plugin] prepare for next development iteration 2019-11-04 08:07:30 -08:00
Liam Newman
438f5d1b87 [maven-release-plugin] prepare release github-api-1.96 2019-11-04 08:07:19 -08:00
dependabot-preview[bot]
fadd6d7978 Bump maven-source-plugin from 3.1.0 to 3.2.0
Bumps [maven-source-plugin](https://github.com/apache/maven-source-plugin) from 3.1.0 to 3.2.0.
- [Release notes](https://github.com/apache/maven-source-plugin/releases)
- [Commits](https://github.com/apache/maven-source-plugin/compare/maven-source-plugin-3.1.0...maven-source-plugin-3.2.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-11-04 13:12:37 +00:00
Liam Newman
5026262273 Merge pull request #578 from martinvanzijl/issue_457_create_team_with_repo_access_fix
GHOrganization.createTeam now adds team to specified repositories
2019-11-01 10:50:53 -07:00
Liam Newman
5b53fba020 Merge pull request #581 from martinvanzijl/issue_546_list_repository_topics
Add method to list repository topics
2019-11-01 09:33:10 -07:00
Liam Newman
3892e6e16f Merge branch 'master' into issue_457_create_team_with_repo_access_fix 2019-11-01 09:30:50 -07:00
Liam Newman
33467de763 Formatting and snapshot cleanup 2019-11-01 09:30:33 -07:00
Martin van Zijl
f3528d97c2 Move team cleanup to @Before method as per GitHub review.
Removed constant for TEAM_NAME as it is now only used once in
the method.
2019-11-01 14:48:20 +13:00
Liam Newman
6fb3b01bf0 Fix gpg signing 2019-10-31 18:10:04 -07:00
Martin van Zijl
e3c9cec440 Fixed typo in comment: listTopics() not getTopics(). 2019-11-01 13:48:20 +13:00
Liam Newman
0e011425fb Merge pull request #586 from PauloMigAlmeida/master
[Documentation] :: Add GitHub App Developer Guide
2019-10-31 17:47:23 -07:00
Liam Newman
ba658f7fea Merge branch 'master' into master 2019-10-31 17:47:12 -07:00
Liam Newman
0e6087143b Merge pull request #587 from bitwiseman/site-build
Fix site errors
2019-10-31 17:46:45 -07:00
Liam Newman
5f967e6307 Fix javadoc on java 11 2019-10-31 17:41:05 -07:00
Martin van Zijl
2eb8ce632c Merge branch 'master' into issue_546_list_repository_topics 2019-11-01 13:35:57 +13:00
Liam Newman
f25dbd15d9 Stabilize time check 2019-10-31 16:10:34 -07:00
PauloMigAlmeida
cc5ea77170 Merge branch 'master' of https://github.com/kohsuke/github-api 2019-11-01 12:02:34 +13:00
PauloMigAlmeida
e323644af2 Correcting typos as pointed out during the code review
Signed-off-by: PauloMigAlmeida <paulo.miguel.almeida.rodenas@gmail.com>
2019-11-01 11:58:16 +13:00
Liam Newman
61f3a3219f Fix tt incompatible tags 2019-10-31 15:41:09 -07:00
Liam Newman
4dcf5dbc13 More pom fixes 2019-10-31 14:24:29 -07:00
Liam Newman
8faecba0a2 Fix site errors 2019-10-31 13:33:14 -07:00
Liam Newman
739551cbe3 Remove old index 2019-10-31 13:01:58 -07:00
PauloMigAlmeida
24a2e42881 [Documentation] :: Add GitHub Developer Guide
Signed-off-by: PauloMigAlmeida <paulo.miguel.almeida.rodenas@gmail.com>
2019-11-01 02:02:07 +13:00
Liam Newman
6921754c99 Merge pull request #585 from github-api/add-code-of-conduct-1
Create CODE_OF_CONDUCT.md
2019-10-30 17:22:09 -07:00
Liam Newman
d8827a0b44 Create CODE_OF_CONDUCT.md 2019-10-30 17:21:56 -07:00
Liam Newman
a48091988f Update release-drafter.yml 2019-10-30 17:04:40 -07:00
Liam Newman
9bd9c9cf1f Create release-drafter.yml 2019-10-30 16:29:26 -07:00
Liam Newman
695692285b Merge pull request #579 from martinvanzijl/issue_512_methods_to_update_milestones
Add methods to update and delete milestones.
2019-10-30 15:47:50 -07:00
Liam Newman
03edacf7b6 Enable test for Milestone due date update 2019-10-30 15:05:35 -07:00
Liam Newman
4802c97e89 Fix GitHub.printDate()
GitHub.printDate() was not setting GMT timezone resulting in completely bogus output.
2019-10-30 14:57:56 -07:00
Liam Newman
9fc24d1981 Merge branch 'master' into issue_512_methods_to_update_milestones 2019-10-30 12:57:18 -07:00
Liam Newman
d4ddf453b0 Merge pull request #580 from martinvanzijl/issue_529_fix_get_deployment_by_id
Fix for getting deployment by id
2019-10-30 12:55:58 -07:00
Liam Newman
c0117f07cf Merge pull request #583 from PauloMigAlmeida/master
Convenience method to auth with app installation token && documentation examples
2019-10-30 12:54:28 -07:00
Paulo Miguel Almeida
8a88c14b13 Add convenience method to authenticate with app installation tokens;
Convert existing markdown doc to APT due to formatting features;
Replace occurrences of kohsuke user to github-api org where applicable;
Fix repositoryIds method on GHAppCreateTokenBuilder;

Signed-off-by: PauloMigAlmeida <paulo.miguel.almeida.rodenas@gmail.com>
2019-10-30 22:18:12 +13:00
Martin van Zijl
a5b6302a69 Add method to list repository topics.
For #546.

The method to update repository topics does not work yet. It may
not have been implemented in the underlying API.
2019-10-30 15:05:09 +13:00
Martin van Zijl
9f29d4619d Fix for getting deployment by id.
Fixes #529.
2019-10-30 13:13:06 +13:00
Martin van Zijl
f4b9dd7d7b Add methods to update and delete milestones.
Fixes #512.
2019-10-30 12:20:06 +13:00
Martin van Zijl
c0a4152b00 GHOrganization.createTeam now adds team to specified repositories.
Fixes #457.
2019-10-29 17:49:41 +13:00
Liam Newman
efb87c5a9e Adjust Jacoco targets to further point to untouched classes. 2019-10-25 19:09:26 -07:00
Liam Newman
061e8bb662 Stop printing to System 2019-10-25 18:33:54 -07:00
Liam Newman
a4f42b2948 Add more tests from AppTest 2019-10-25 18:31:40 -07:00
Liam Newman
cb2fcd3a9e Enable Jacoco on at has-it-been-touched reporting 2019-10-25 18:19:13 -07:00
Liam Newman
1d004a35a0 Merge pull request #510 from awittha/get-user-orgs
Added getUserPublicOrganizations method
2019-10-24 18:32:09 -07:00
Austin Witt
c763c02018 [added] unit tests for getUserPublicOrganizations(...) 2019-10-24 11:03:37 -05:00
Austin Witt
eb36cb4436 Merge remote-tracking branch 'upstream/master' into get-user-orgs 2019-10-23 14:39:54 -05:00
Liam Newman
72d4b9bf62 Merge pull request #525 from vbehar/draft-pr
Add support for draft pull requests
2019-10-21 16:01:02 -07:00
Liam Newman
81ea138f41 Test and fixes for draft pull request 2019-10-21 15:38:04 -07:00
Liam Newman
1bbc66ad62 Merge remote-tracking branch 'github-api/master' into draft-pr 2019-10-21 14:34:40 -07:00
Liam Newman
e7348df372 Merge pull request #575 from romani/patch-1
bump jackson-databind to 2.10.0 to avoid security alert
2019-10-21 12:56:12 -07:00
Roman Ivanov
550e060647 bump jackson-databind to 2.10.0 to avoid security alert 2019-10-20 06:37:28 -07:00
Liam Newman
2970a58e95 Merge branch 'master' into draft-pr 2019-10-18 13:00:39 -07:00
Liam Newman
e0efa04fd4 Merge pull request #574 from github-api/dependabot/maven/com.github.tomakehurst-wiremock-jre8-standalone-2.25.1
Bump wiremock-jre8-standalone from 2.25.0 to 2.25.1
2019-10-18 13:00:14 -07:00
dependabot-preview[bot]
4d24088982 Bump wiremock-jre8-standalone from 2.25.0 to 2.25.1
Bumps [wiremock-jre8-standalone](https://github.com/tomakehurst/wiremock) from 2.25.0 to 2.25.1.
- [Release notes](https://github.com/tomakehurst/wiremock/releases)
- [Commits](https://github.com/tomakehurst/wiremock/compare/2.25.0...2.25.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-18 19:58:47 +00:00
Liam Newman
baba9f5de6 Merge pull request #573 from github-api/dependabot/maven/hamcrest.version-2.2
Bump hamcrest.version from 2.1 to 2.2
2019-10-18 12:57:35 -07:00
dependabot-preview[bot]
c35cd63d0e Bump hamcrest.version from 2.1 to 2.2
Bumps `hamcrest.version` from 2.1 to 2.2.

Updates `hamcrest` from 2.1 to 2.2
- [Release notes](https://github.com/hamcrest/JavaHamcrest/releases)
- [Changelog](https://github.com/hamcrest/JavaHamcrest/blob/master/CHANGES.md)
- [Commits](https://github.com/hamcrest/JavaHamcrest/compare/v2.1...v2.2)

Updates `hamcrest-core` from 2.1 to 2.2
- [Release notes](https://github.com/hamcrest/JavaHamcrest/releases)
- [Changelog](https://github.com/hamcrest/JavaHamcrest/blob/master/CHANGES.md)
- [Commits](https://github.com/hamcrest/JavaHamcrest/compare/v2.1...v2.2)

Updates `hamcrest-library` from 2.1 to 2.2
- [Release notes](https://github.com/hamcrest/JavaHamcrest/releases)
- [Changelog](https://github.com/hamcrest/JavaHamcrest/blob/master/CHANGES.md)
- [Commits](https://github.com/hamcrest/JavaHamcrest/compare/v2.1...v2.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-16 23:05:29 +00:00
Liam Newman
80fa389ce3 Fix GHContent.read()
Fixes #487
2019-10-11 15:21:57 -07:00
Liam Newman
8ec861c9fe Merge pull request #563 from bitwiseman/paged_iterable_closure
Simplify creation of PagedIterables from requests
2019-10-11 13:20:17 -07:00
Liam Newman
837400fb5e Merge pull request #572 from sullis/java-matrix-jdk13
GitHub workflow: add JDK 13 to build matrix
2019-10-11 13:18:00 -07:00
Liam Newman
ec4525b8ff Merge branch 'master' into java-matrix-jdk13 2019-10-11 13:13:09 -07:00
Liam Newman
281c927971 Update GHIssueEvent PagedIterable 2019-10-11 13:11:08 -07:00
Liam Newman
9dd44c13e4 Update for AuthorizationList 2019-10-11 13:05:13 -07:00
Liam Newman
f28edbcf8f Simplify creation of PagedIterables from requests 2019-10-11 13:05:13 -07:00
Liam Newman
29e147f992 wrupUp() package private 2019-10-11 13:02:42 -07:00
Sean C. Sullivan
830f4231e1 GitHub workflow: add JDK 13 to build matrix 2019-10-11 12:08:03 -07:00
Liam Newman
7d65e31055 Merge pull request #484 from martinvanzijl/issue_466_edit_gists
Add support for editing Gists
2019-10-11 11:46:56 -07:00
Liam Newman
dec7a91b5b Merge pull request #479 from martinvanzijl/issue_376_issue_events
Add issue events API
2019-10-11 11:44:03 -07:00
Liam Newman
1ba630c221 Minor Gist updater improvement 2019-10-11 11:21:11 -07:00
Martin van Zijl
7d3387fb96 Updated unit tests. 2019-10-11 16:37:08 +13:00
Liam Newman
a0c0de28d7 Move a few more tests to use temp repo 2019-10-09 13:41:00 -07:00
Liam Newman
dc31d52f83 Add facility to create and auto-cleanup temp repos 2019-10-09 13:00:21 -07:00
Martin van Zijl
620c822dac Updates per review on GitHub:
- Created class GHGistUpdater to do the updating.
- Added unit tests.
2019-10-10 07:08:05 +13:00
Liam Newman
5990f5ae22 Merge pull request #567 from jberglund-BSFT/master
Add merge options to GHRepository
2019-10-09 11:02:54 -07:00
Martin van Zijl
37329a50d4 Merge branch 'master' into issue_466_edit_gists 2019-10-10 05:43:10 +13:00
Martin van Zijl
550597f72e Make unit test output neater. 2019-10-09 15:11:02 +13:00
Martin van Zijl
2aa4022e2c Updated per review.
- Created separate class for GHIssueEvent instead of nested classes.
- Renamed test class accordingly.

Other fixes:

- Changed id type to long.
- Updated test cases.
- Added toString() method.
2019-10-09 14:59:08 +13:00
Martin van Zijl
b40741b14d Merge branch 'issue_376_issue_events' of https://github.com/martinvanzijl/github-api into issue_376_issue_events 2019-10-09 14:03:27 +13:00
Joey Berglund
3c739d889e Merge branch 'master' into master 2019-10-08 15:04:55 -05:00
Liam Newman
24a92a133e Merge branch 'master' into issue_376_issue_events 2019-10-08 11:04:22 -07:00
Liam Newman
ce97eb5b40 Merge pull request #482 from martinvanzijl/issue_467_add_user_to_org
Add method to invite user to organization
2019-10-08 11:04:01 -07:00
Liam Newman
7a4e3c480e Merge branch 'master' into issue_467_add_user_to_org 2019-10-08 10:59:27 -07:00
Liam Newman
eefa710839 Merge branch 'master' into issue_466_edit_gists 2019-10-08 10:59:09 -07:00
Liam Newman
4c3e1afcca Merge branch 'master' into get-user-orgs 2019-10-08 10:57:48 -07:00
Liam Newman
c1a77ada5d Merge branch 'master' into draft-pr 2019-10-08 10:55:51 -07:00
Liam Newman
5671e5ed67 Merge branch 'master' into master 2019-10-08 10:54:23 -07:00
Liam Newman
2fdc5a8541 Merge pull request #562 from sullis/github-workflow-java-matrix
GitHub workflow: enable Java matrix [ '1.8.0', '11.0.x' ]
2019-10-08 10:51:37 -07:00
Liam Newman
297dbae247 Merge branch 'master' into github-workflow-java-matrix 2019-10-08 10:47:19 -07:00
Liam Newman
0910cdf3a4 Add test for bridge method 2019-10-08 10:37:51 -07:00
jberglund
6877fb5c74 add unit test 2019-10-08 11:20:34 -05:00
Liam Newman
2d65daa8c9 Merge branch 'master' into master 2019-10-08 08:21:54 -07:00
Sean C. Sullivan
dab4cb6186 cleanup pom.xml 2019-10-07 22:46:40 -07:00
Sean C. Sullivan
40773a2b49 GitHub workflow: enable Java matrix [ '1.8.0', '11.0.x' ] 2019-10-07 22:37:58 -07:00
Liam Newman
7e0d61a6fc Merge pull request #481 from martinvanzijl/issue_459_list_authorizations
Added method to list authorizations
2019-10-07 19:04:00 -07:00
Liam Newman
7f9620d75f Delete Foo.java 2019-10-07 18:46:02 -07:00
Martin van Zijl
3559aef1a1 Fixes per review.
- Added missing brace at end of listMyAuthorizations().
- Added unit test for listMyAuthorizations().
2019-10-08 13:21:48 +13:00
Martin van Zijl
94ceb5eaaf Merge branch 'master' into issue_459_list_authorizations 2019-10-08 12:42:18 +13:00
Martin van Zijl
778ca76d22 Merge branch 'issue_376_issue_events' of https://github.com/martinvanzijl/github-api into issue_376_issue_events 2019-10-08 12:34:44 +13:00
Martin van Zijl
b1c0e41c5c Merge branch 'master' into issue_376_issue_events 2019-10-08 12:31:30 +13:00
Liam Newman
f826edd097 Merge pull request #564 from github-api/dependabot/maven/com.squareup.okio-okio-2.4.1
Bump okio from 2.4.0 to 2.4.1
2019-10-07 14:09:42 -07:00
Liam Newman
edc7c4a4b8 Merge pull request #565 from github-api/dependabot/maven/com.google.code.gson-gson-2.8.6
Bump gson from 2.8.5 to 2.8.6
2019-10-07 14:09:11 -07:00
Liam Newman
dafdc66d25 Merge pull request #568 from bitwiseman/more-tests
More tests
2019-10-07 14:08:45 -07:00
Liam Newman
0d135f14bb Add more CI tests 2019-10-07 14:01:32 -07:00
Liam Newman
568c08d0e9 Separate connection sensitive tests 2019-10-07 13:09:27 -07:00
Liam Newman
87410e295e Add more tests to ci 2019-10-07 13:04:13 -07:00
Joey Berglund
b163e68950 Merge branch 'master' into master 2019-10-07 08:41:56 -05:00
Joey Berglund
88b006e957 Update GHRepository.java 2019-10-07 08:39:38 -05:00
dependabot-preview[bot]
477f2f2814 Bump gson from 2.8.5 to 2.8.6
Bumps [gson](https://github.com/google/gson) from 2.8.5 to 2.8.6.
- [Release notes](https://github.com/google/gson/releases)
- [Changelog](https://github.com/google/gson/blob/master/CHANGELOG.md)
- [Commits](https://github.com/google/gson/compare/gson-parent-2.8.5...gson-parent-2.8.6)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-07 08:09:06 +00:00
dependabot-preview[bot]
933d99c23b Bump okio from 2.4.0 to 2.4.1
Bumps [okio](https://github.com/square/okio) from 2.4.0 to 2.4.1.
- [Release notes](https://github.com/square/okio/releases)
- [Changelog](https://github.com/square/okio/blob/master/CHANGELOG.md)
- [Commits](https://github.com/square/okio/compare/parent-2.4.0...2.4.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-07 08:08:48 +00:00
Martin van Zijl
d3a0c5ded1 Added unit test for adding user to organization. 2019-10-07 15:34:13 +13:00
Martin van Zijl
1e173ddc24 Merge branch 'master' of https://github.com/kohsuke/github-api into issue_467_add_user_to_org 2019-10-07 13:56:08 +13:00
Liam Newman
ca404cb33b Merge branch 'master' into issue_466_edit_gists 2019-10-05 19:40:56 -07:00
Liam Newman
f0dc7d5b02 Merge pull request #532 from farmdawgnation/team-pr-review-requests
Add support for team pr review requests
2019-10-05 19:39:55 -07:00
Liam Newman
933702376f Update Tests to check for lazy loading and refresh 2019-10-05 14:35:13 -07:00
Liam Newman
e08896775b Add Refreshable interfrace and use it in GHTeam and GHPullRequest 2019-10-05 14:17:17 -07:00
Matt Farmer
d610e46f8e Add a test for team review requests 2019-10-05 09:19:28 -04:00
Matt Farmer
7d1989f5a2 Materialize requested_teams from the teams API
We don't get the full object when we retrieve a PR, so when we see
requested teams we need to materialize them from the API
2019-10-05 09:13:13 -04:00
Matt Farmer
5c1e371427 Rebuild wiremock for test review requests 2019-10-05 08:35:12 -04:00
Matt Farmer
dbd9d51747 Merge remote-tracking branch 'upstream/master' into team-pr-review-requests 2019-10-05 08:29:27 -04:00
Liam Newman
fdf5d3f72d Merge pull request #475 from immanuelqrw/label-description
Adding Label description property
2019-10-04 22:28:11 -07:00
Liam Newman
2719867a86 Fix up Label Description and tests 2019-10-04 22:23:53 -07:00
Liam Newman
0240412ad2 Merge remote-tracking branch 'github-api/master' into label-description 2019-10-04 21:44:06 -07:00
Liam Newman
7c065c1205 Merge pull request #477 from martinvanzijl/issue_330_statistics
Add statistics API.
2019-10-04 21:38:08 -07:00
Liam Newman
f9aa1ad1f2 Fix JSON API FB warning 2019-10-04 21:34:55 -07:00
Liam Newman
5feffdf544 Minor fixups after merge from master
Rerecorded WireMock files with newer framework
2019-10-04 21:29:08 -07:00
Liam Newman
4e56b8bb78 Merge branch 'master' into issue_330_statistics 2019-10-04 21:12:35 -07:00
Liam Newman
845017313c Merge pull request #545 from gskjold/issue_425_projects_columns_cards
Support for projects
2019-10-04 21:10:51 -07:00
Liam Newman
dc2830d94f Enable Content test 2019-10-04 21:06:15 -07:00
Liam Newman
552edf8698 Switch to WireMockMultiServerRule as base 2019-10-04 21:06:00 -07:00
Liam Newman
41c51646fe Rename GitHubApiWireMockRule to GitHubWireMockRule 2019-10-04 21:02:44 -07:00
Joey Berglund
a42024bdbc Update GHRepository.java 2019-10-04 16:28:28 -05:00
Liam Newman
20cfb26a7f Disable Licence content test
Need to mock raw.githubusercontent.com to make this work
2019-10-04 11:09:05 -07:00
Liam Newman
3972d11827 WireMock License Test 2019-10-04 10:30:22 -07:00
Liam Newman
5cc88a0075 WireMock Project Tests 2019-10-04 10:27:47 -07:00
Gunnar Skjold
fc08711111 Expanded GHProject with columns and cards. Also added tests for projects, columns and cards 2019-10-04 10:11:18 -07:00
Martin van Zijl
b20c2babec Added support for projects.
Fixes issue #425
2019-10-04 10:11:18 -07:00
Martin van Zijl
cb0facc6ef Updates per GH review.
- Marked getContributorStats(bool) as deprecated, preview
- Moved "stats/" string to getApiTailUrl()
2019-10-05 05:43:23 +13:00
Liam Newman
78abb2edcb Merge pull request #530 from bozaro/request-log
Add GitHub API requests logging
2019-10-04 09:15:09 -07:00
Liam Newman
7d350d9def Merge pull request #561 from github-api/dependabot/maven/org.eclipse.jgit-org.eclipse.jgit-5.5.1.201910021850-r
Bump org.eclipse.jgit from 5.5.0.201909110433-r to 5.5.1.201910021850-r
2019-10-04 08:15:48 -07:00
dependabot-preview[bot]
48d7daf2c4 Bump org.eclipse.jgit from 5.5.0.201909110433-r to 5.5.1.201910021850-r
Bumps org.eclipse.jgit from 5.5.0.201909110433-r to 5.5.1.201910021850-r.

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-04 08:22:03 +00:00
Liam Newman
2782059d88 Merge branch 'master' into request-log 2019-10-04 00:44:21 -07:00
Liam Newman
0ca10bc2ac Merge branch 'master' into issue_459_list_authorizations 2019-10-04 00:43:14 -07:00
Liam Newman
880abe2305 Merge branch 'master' into issue_467_add_user_to_org 2019-10-04 00:41:50 -07:00
Liam Newman
22f61d6225 Merge branch 'master' into issue_376_issue_events 2019-10-04 00:41:15 -07:00
Liam Newman
4fbaa425fb Merge branch 'master' into issue_466_edit_gists 2019-10-04 00:36:18 -07:00
Liam Newman
e81e228f03 Merge branch 'master' into issue_330_statistics 2019-10-04 00:01:36 -07:00
Liam Newman
1076f89954 Merge branch 'master' into label-description 2019-10-03 23:56:27 -07:00
Liam Newman
9c6f977202 Merge branch 'master' into get-user-orgs 2019-10-03 23:55:56 -07:00
Martin van Zijl
bd23ba6077 Added Wiremock test files. 2019-10-04 16:27:41 +13:00
Martin van Zijl
c7af56d0ed Changes per review on GitHub.
- Moved statistics methods from GHRepository to new class GHRepositoryStatistics
- Updated StatisticsTest to suit.
- For ContributorStats, put the "wait-till-ready" loop in the accessor method.
  I'm planning to do something similar for the rest.
2019-10-04 16:23:26 +13:00
Liam Newman
8da6db9fcc Merge pull request #522 from PauloMigAlmeida/master
Implement GitHub App API methods
2019-10-03 19:29:37 -07:00
Liam Newman
2fe7342fd7 Merge branch 'master' into master 2019-10-03 19:07:40 -07:00
Liam Newman
f6221144a8 Merge pull request #478 from martinvanzijl/issue_460_team_description_field
Added description field to GHTeam class.
2019-10-03 17:37:52 -07:00
Liam Newman
872d713e50 Fix one more case of connecting outside the proxy 2019-10-03 17:34:52 -07:00
Liam Newman
d5b04f572b Fixed list traversal for paged queries 2019-10-03 17:23:31 -07:00
PauloMigAlmeida
0f7a5f1c08 Merge from upstream;
Remove servlet exclusion due to previous JDK version;

Signed-off-by: PauloMigAlmeida <paulo.miguel.almeida.rodenas@gmail.com>
2019-10-04 11:59:58 +13:00
PauloMigAlmeida
a163c565a8 Merge branch 'master' of https://github.com/kohsuke/github-api
 Conflicts:
	src/main/java/org/kohsuke/github/GitHubBuilder.java
	src/test/java/org/kohsuke/github/GitHubTest.java
2019-10-04 11:56:38 +13:00
Liam Newman
413a316b15 Record snapshot for test 2019-10-03 14:51:46 -07:00
Liam Newman
65a92a49b5 Merge remote-tracking branch 'github-api/master' into issue_460_team_description_field 2019-10-03 14:44:04 -07:00
Sharath Babu
563507ca21 add setPrivate functionality on repos 2019-10-03 14:38:26 -07:00
Liam Newman
21b2d02f0a Enable GHOrganizationTest in CI 2019-10-03 14:20:18 -07:00
Liam Newman
19e1a00fd7 Rename mapping files to include index 2019-10-03 14:05:15 -07:00
Liam Newman
a02a6a22d0 Move to Gson for formatting json 2019-10-03 13:49:53 -07:00
Liam Newman
3488421f67 More WireMock tests 2019-10-03 12:34:32 -07:00
Liam Newman
34a961088c Initial attempt at auto-format of JSON 2019-10-03 09:06:31 -07:00
Liam Newman
b35509150a Enable part of AppTest in CI 2019-10-02 15:27:22 -07:00
Liam Newman
d096aa2065 Merge pull request #558 from github-api/dependabot/maven/com.squareup.okio-okio-2.4.0
Bump okio from 2.2.2 to 2.4.0
2019-10-02 09:12:45 -07:00
dependabot-preview[bot]
efd5bef102 Bump okio from 2.2.2 to 2.4.0
Bumps [okio](https://github.com/square/okio) from 2.2.2 to 2.4.0.
- [Release notes](https://github.com/square/okio/releases)
- [Changelog](https://github.com/square/okio/blob/master/CHANGELOG.md)
- [Commits](https://github.com/square/okio/compare/2.2.2...parent-2.4.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-02 15:57:35 +00:00
Liam Newman
b8c6e44ab6 Update okhttp3 (with Java 8)
This version of okhttp3 is the last to suppurt UrlFactory, but we've replaced it anyway in preparation for future updates.
2019-10-01 14:05:50 -07:00
Liam Newman
9a91cc43e2 Merge pull request #542 from bitwiseman/cache-fix
Improved OkHttpConnector caching behavior
2019-10-01 13:11:26 -07:00
Liam Newman
f4cbab52a7 Merge branch 'master' into cache-fix 2019-10-01 13:07:35 -07:00
Liam Newman
57b58cf203 Merge pull request #557 from github-api/dependabot/maven/org.mockito-mockito-core-3.1.0
Bump mockito-core from 3.0.0 to 3.1.0
2019-10-01 08:25:59 -07:00
dependabot-preview[bot]
9ba8ae08a1 Bump mockito-core from 3.0.0 to 3.1.0
Bumps [mockito-core](https://github.com/mockito/mockito) from 3.0.0 to 3.1.0.
- [Release notes](https://github.com/mockito/mockito/releases)
- [Commits](https://github.com/mockito/mockito/compare/v3.0.0...v3.1.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-10-01 12:54:01 +00:00
Liam Newman
dfe81f510e Add None and Zero Cache tests to CI 2019-09-30 16:23:08 -07:00
Liam Newman
f3a0b35442 Updated Tests to have non-cache tests run in CI 2019-09-30 11:05:11 -07:00
Liam Newman
64e3be3bc7 Merge branch 'master' into cache-fix 2019-09-30 09:13:52 -07:00
Liam Newman
4c82d1c56e Merge pull request #556 from github-api/dependabot/maven/com.github.tomakehurst-wiremock-jre8-standalone-2.25.0
Bump wiremock-jre8-standalone from 2.24.1 to 2.25.0
2019-09-30 09:13:06 -07:00
Liam Newman
d8451fc2f5 Implement new abstract methods from Admin 2019-09-30 09:00:55 -07:00
dependabot-preview[bot]
8078423252 Bump wiremock-jre8-standalone from 2.24.1 to 2.25.0
Bumps [wiremock-jre8-standalone](https://github.com/tomakehurst/wiremock) from 2.24.1 to 2.25.0.
- [Release notes](https://github.com/tomakehurst/wiremock/releases)
- [Commits](https://github.com/tomakehurst/wiremock/compare/2.24.1...2.25.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-30 08:40:16 +00:00
Liam Newman
68176b5695 Merge branch 'master' into draft-pr 2019-09-29 18:36:34 -07:00
Liam Newman
1bf7833959 Merge branch 'master' into request-log 2019-09-29 18:35:53 -07:00
Liam Newman
89770b922d Change listKeys to getKeys 2019-09-29 18:33:08 -07:00
Liam Newman
716947bbb1 Merge branch 'master' into draft-pr 2019-09-27 10:38:23 -07:00
Liam Newman
47e0d7786b Merge branch 'master' into cache-fix 2019-09-27 10:37:26 -07:00
Arngrimur Bjarnason
55f9c40bba Merge branch 'master' into getKeysForUser 2019-09-27 08:24:49 +02:00
Martin van Zijl
51afa30732 Added unit tests. 2019-09-26 14:32:30 +12:00
Liam Newman
23c07316ee Merge branch 'master' into label-description 2019-09-25 17:28:23 -07:00
Liam Newman
e740f52e5e Merge pull request #480 from martinvanzijl/issue_381_branch_url_escaping
Escape special characters in branch URLs
2019-09-25 17:15:50 -07:00
Liam Newman
a731109747 Add tests for URLEncoding 2019-09-25 17:11:46 -07:00
Martin van Zijl
a50a011eb3 Issue #381 - Escape branch URL.
This is using the "old" HTTP.UTF_8 Charset, since the new
StandardCharsets doesn't compile.
2019-09-25 16:59:58 -07:00
Liam Newman
e22c6d3a94 Merge branch 'master' into issue_330_statistics 2019-09-25 16:57:36 -07:00
Liam Newman
50fb9c1795 Merge pull request #473 from joaoe/issue-472-archive-repository
Implemented GitHub.doArchive
2019-09-25 16:55:12 -07:00
Liam Newman
22575c9a01 Add test for archive method 2019-09-25 16:48:54 -07:00
João Eiras
2934922cb5 Implemented GitHub.doArchive
doArchive() will mark a repository as archived.

Issue #472
2019-09-25 16:30:44 -07:00
Liam Newman
9042ff46c7 Clean up Previews 2019-09-25 15:47:07 -07:00
Liam Newman
a1a91539c2 Merge branch 'master' into getKeysForUser 2019-09-25 10:13:39 -07:00
Liam Newman
468f4f94a3 Merge pull request #554 from github-api/dependabot/maven/org.apache.maven.plugins-maven-surefire-plugin-2.22.2
Bump maven-surefire-plugin from 2.22.1 to 2.22.2
2019-09-25 10:10:02 -07:00
Liam Newman
3ebd35437e Merge pull request #552 from github-api/dependabot/maven/org.apache.commons-commons-lang3-3.9
Bump commons-lang3 from 3.7 to 3.9
2019-09-25 10:09:33 -07:00
dependabot-preview[bot]
a166bbadad Bump maven-surefire-plugin from 2.22.1 to 2.22.2
Bumps [maven-surefire-plugin](https://github.com/apache/maven-surefire) from 2.22.1 to 2.22.2.
- [Release notes](https://github.com/apache/maven-surefire/releases)
- [Commits](https://github.com/apache/maven-surefire/compare/surefire-2.22.1...surefire-2.22.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-25 17:08:56 +00:00
Liam Newman
7ff07a132a Merge branch 'master' into dependabot/maven/org.apache.commons-commons-lang3-3.9 2019-09-25 10:08:33 -07:00
Liam Newman
6f297bcbb8 Merge pull request #555 from github-api/dependabot/maven/commons-io-commons-io-2.6
Bump commons-io from 1.4 to 2.6
2019-09-25 10:07:45 -07:00
dependabot-preview[bot]
1c023e15af Bump commons-io from 1.4 to 2.6
Bumps commons-io from 1.4 to 2.6.

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-25 07:33:21 +00:00
dependabot-preview[bot]
37f96848a7 Bump commons-lang3 from 3.7 to 3.9
Bumps commons-lang3 from 3.7 to 3.9.

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-25 07:32:00 +00:00
Liam Newman
3d04765f51 Merge branch 'master' into issue_330_statistics 2019-09-24 18:19:35 -07:00
Liam Newman
e1152fa549 Merge branch 'master' into issue_466_edit_gists 2019-09-24 14:34:15 -07:00
Liam Newman
ab47896f17 Merge branch 'master' into cache-fix 2019-09-24 14:29:36 -07:00
Liam Newman
4f13565e51 Merge pull request #549 from github-api/dependabot/maven/com.infradna.tool-bridge-method-annotation-1.18
Bump bridge-method-annotation from 1.17 to 1.18
2019-09-24 14:29:03 -07:00
dependabot-preview[bot]
7ab93a59e2 Bump bridge-method-annotation from 1.17 to 1.18
Bumps [bridge-method-annotation](https://github.com/infradna/bridge-method-injector) from 1.17 to 1.18.
- [Release notes](https://github.com/infradna/bridge-method-injector/releases)
- [Commits](https://github.com/infradna/bridge-method-injector/compare/bridge-method-injector-parent-1.17...bridge-method-injector-parent-1.18)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-24 21:26:18 +00:00
Liam Newman
943c0d022b Merge pull request #551 from github-api/dependabot/maven/commons-codec-commons-codec-1.13
Bump commons-codec from 1.7 to 1.13
2019-09-24 14:24:58 -07:00
dependabot-preview[bot]
bea8922c39 Bump commons-codec from 1.7 to 1.13
Bumps [commons-codec](https://github.com/apache/commons-codec) from 1.7 to 1.13.
- [Release notes](https://github.com/apache/commons-codec/releases)
- [Changelog](https://github.com/apache/commons-codec/blob/master/RELEASE-NOTES.txt)
- [Commits](https://github.com/apache/commons-codec/compare/1.7...commons-codec-1.13)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-24 21:23:03 +00:00
Liam Newman
97c96a7ee1 Merge pull request #550 from github-api/dependabot/maven/com.github.spotbugs-spotbugs-maven-plugin-3.1.12.2
Bump spotbugs-maven-plugin from 3.1.11 to 3.1.12.2
2019-09-24 14:21:43 -07:00
dependabot-preview[bot]
3d831ba7e8 Bump spotbugs-maven-plugin from 3.1.11 to 3.1.12.2
Bumps [spotbugs-maven-plugin](https://github.com/spotbugs/spotbugs-maven-plugin) from 3.1.11 to 3.1.12.2.
- [Release notes](https://github.com/spotbugs/spotbugs-maven-plugin/releases)
- [Commits](https://github.com/spotbugs/spotbugs-maven-plugin/compare/spotbugs-maven-plugin-3.1.11...spotbugs-maven-plugin-3.1.12.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-24 21:19:00 +00:00
Liam Newman
df749a98cb Merge pull request #547 from github-api/dependabot/maven/org.eclipse.jgit-org.eclipse.jgit-5.5.0.201909110433-r
Bump org.eclipse.jgit from 4.9.0.201710071750-r to 5.5.0.201909110433-r
2019-09-24 14:17:31 -07:00
dependabot-preview[bot]
22bbc9c621 Bump org.eclipse.jgit from 4.9.0.201710071750-r to 5.5.0.201909110433-r
Bumps org.eclipse.jgit from 4.9.0.201710071750-r to 5.5.0.201909110433-r.

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-24 19:46:06 +00:00
Liam Newman
30def4e515 Update jackson-databind to 2.9.10 2019-09-24 12:43:43 -07:00
Matt Farmer
cf8be37310 Correct test run + add sample data 2019-09-21 10:29:48 -04:00
Matt Farmer
12409df446 Merge remote-tracking branch 'upstream/master' into team-pr-review-requests 2019-09-21 09:56:12 -04:00
Martin van Zijl
3452a08de3 Added more detail to unit tests.
Added another accessor method.
2019-09-20 16:27:32 +12:00
Liam Newman
425ea0579e Merge branch 'master' into label-description 2019-09-17 13:33:50 -07:00
Arngrimur Bjarnason
22afb769af Adding wiremocks 2019-09-17 14:56:43 +02:00
Arngrimur Bjarnason
884eae269e Adding possiblity to get ssh keys 2019-09-17 14:39:46 +02:00
PauloMigAlmeida
59a973970e Remove duplicated wiremock dependency
Signed-off-by: PauloMigAlmeida <paulo.miguel.almeida.rodenas@gmail.com>
2019-09-15 10:57:22 +12:00
PauloMigAlmeida
225383464a Merge remote-tracking branch 'origin/master' 2019-09-15 10:52:53 +12:00
PauloMigAlmeida
3d82731325 Update tests using the new wiremock structure as per requested
Signed-off-by: PauloMigAlmeida <paulo.miguel.almeida.rodenas@gmail.com>
2019-09-15 10:52:22 +12:00
PauloMigAlmeida
dacdf08309 Merge branch 'master' of https://github.com/kohsuke/github-api 2019-09-14 17:00:24 +12:00
Martin van Zijl
ad281adc97 Unit tests and fixes.
Fixed issue with getCodeFrequency() where it would occasionally throw
an exception when the statistics were still being generated.

Added comment about throwing an exception as a possibility when
202 is returned.
2019-09-14 10:39:59 +12:00
Liam Newman
80741c7773 Use CacheControl and only check for cache in constructor 2019-09-12 13:57:28 -07:00
Liam Newman
532f7a4b17 Merge branch 'master' into cache-fix 2019-09-11 22:48:26 -07:00
Liam Newman
5e87d582e4 Add tests showing cache performance 2019-09-11 22:05:02 -07:00
Liam Newman
b9bf47aaca Merge pull request #543 from jsoref/grammar
Grammar
2019-09-11 20:48:28 -07:00
Josh Soref
0dba882817 spelling: create a 2019-09-11 19:28:32 -04:00
Josh Soref
c419883814 spelling: single 2019-09-11 19:28:24 -04:00
Josh Soref
6f0ccbf2b5 grammar: agreement: returns...organizations 2019-09-11 19:28:14 -04:00
Josh Soref
54332c0bd1 this api is no longer a preview... 2019-09-11 19:27:40 -04:00
Josh Soref
5f80674e89 finish thought... 2019-09-11 19:27:04 -04:00
Josh Soref
c4d0d8ff06 grammar: operations-require 2019-09-11 19:26:47 -04:00
Josh Soref
8ac1b7082a brand: GitHub Enterprise 2019-09-11 19:26:14 -04:00
Josh Soref
f146ae8be4 spelling: user 2019-09-11 19:25:55 -04:00
Josh Soref
e7728fdc94 spelling: log-in 2019-09-11 19:25:44 -04:00
Josh Soref
052122e4d0 spelling: abuse 2019-09-11 19:25:29 -04:00
Josh Soref
38827d2b3d grammar: period at end of sentence (not inside parenthetical) 2019-09-11 19:25:19 -04:00
Liam Newman
9e1f16be27 Fix OkHttpConnector caching 2019-09-10 23:01:50 -07:00
Liam Newman
c845846317 Do not rerun tests
If they failed once, they will fail again.
2019-09-10 23:00:44 -07:00
Liam Newman
9276556f19 Mockito 3.0.0 2019-09-10 22:59:07 -07:00
Liam Newman
c796d18948 Merge pull request #541 from bitwiseman/wiremock-github-rule
Add GitHubApiWireMockRule
2019-09-10 22:54:27 -07:00
Liam Newman
8dee5520cf Add GitHubApiWireMockRule
Separates the WireMock and GitHub API info from project specific code.
2019-09-10 22:42:28 -07:00
Liam Newman
440e13714e Merge branch 'master' into issue_466_edit_gists 2019-09-09 22:04:11 -07:00
Liam Newman
44a70b372d Merge pull request #502 from CodeAndChoke/hashcode_equals
Added equals and hashcode
2019-09-09 22:02:22 -07:00
Liam Newman
504286e96e Merge pull request #540 from bitwiseman/test-run
Working CI Build
2019-09-09 22:01:33 -07:00
Liam Newman
ffdd54d2fa Merge branch 'master' into get-user-orgs 2019-09-09 19:40:00 -07:00
Liam Newman
32804b81c0 Merge pull request #527 from WouterG/patch-1
Remove unnessesairy "throws"
2019-09-09 19:38:09 -07:00
Liam Newman
403b22ade0 Working CI Build
This change automatically turns off tests where we haven't had a chance to implement wiremocking.
They can still be run locally by setting test.github.useProxy (even though most of them do actually use the proxy).
2019-09-09 19:34:09 -07:00
Liam Newman
a4e74abcca Merge branch 'master' into master 2019-09-09 17:19:58 -07:00
Liam Newman
8dcef5bac0 Merge branch 'master' into draft-pr 2019-09-09 16:57:14 -07:00
Liam Newman
49878bc4e3 Merge branch 'master' into patch-1 2019-09-09 16:56:34 -07:00
Liam Newman
3f1a71c8a4 Merge branch 'master' into request-log 2019-09-09 16:54:24 -07:00
Liam Newman
bf9b2c0da3 Merge branch 'master' into team-pr-review-requests 2019-09-09 16:40:00 -07:00
Liam Newman
909a274709 Merge pull request #538 from ewiegs4/pr-query-head
Namespace PR head queries with repo's owner by default
2019-09-09 16:31:21 -07:00
Liam Newman
fc529b8083 Merge remote-tracking branch 'kohsuke/master' into pr-query-head 2019-09-09 16:16:36 -07:00
Liam Newman
f1386f26fb maven-build.yml
Trying to get actions to trigger
2019-09-09 16:15:35 -07:00
Liam Newman
cccd09d329 Delete maven.yml 2019-09-09 16:13:51 -07:00
Liam Newman
0fccf7effe Update maven.yml 2019-09-09 16:06:21 -07:00
Liam Newman
4b91a47c8b Merge branch 'master' into issue_460_team_description_field 2019-09-09 16:01:27 -07:00
Liam Newman
bd40499bbe Improve behavior and documentation for WireMock testing 2019-09-09 15:55:03 -07:00
Liam Newman
c7c8cd76c6 Merge branch 'master' into label-description 2019-09-08 23:58:18 -07:00
Liam Newman
0bb9f0ce41 Merge branch 'master' into pr-query-head 2019-09-08 23:55:34 -07:00
Liam Newman
7136afce8e Update all WireMock data files 2019-09-08 23:33:44 -07:00
Liam Newman
ec17c1de6a Update PullRequestTest for WireMocking 2019-09-08 23:33:30 -07:00
Liam Newman
8d6daef354 Rewrite wiremock rule to snapshot on a per-method basis 2019-09-08 23:33:30 -07:00
Liam Newman
3a09d2de4a Rename README to README.md 2019-09-06 17:07:13 -07:00
Liam Newman
c78e10f92e Merge remote-tracking branch 'kohsuke/master' into pr-query-head 2019-09-06 16:18:49 -07:00
Liam Newman
b113ff35ac Merge pull request #537 from bitwiseman/wiremock
Add WireMock testing facility
2019-09-06 16:17:37 -07:00
Eddie Wiegers
6360024d20 Add test for qualified case. 2019-09-06 16:43:19 -05:00
Martin van Zijl
a7683f6bd7 Added setter and unit tests for GHTeam description field. 2019-09-05 16:23:38 +12:00
Liam Newman
e46a9f3f2a Java 8 required for testing, not for package 2019-09-03 13:16:28 -07:00
Eddie Wiegers
a8d711d4c8 Qualify PR head queries with repo's owner by default 2019-09-03 11:40:33 -05:00
Liam Newman
df74fc67bd Add WireMock tests to CI 2019-08-31 21:55:09 -07:00
Liam Newman
450261abbf Move scenario to json files 2019-08-31 19:52:50 -07:00
Liam Newman
12230edc54 Add UserTest to WireMock 2019-08-31 01:35:21 -07:00
Liam Newman
d1cfcf561b Converted GistTest to WireMock 2019-08-31 01:25:25 -07:00
Liam Newman
d143f5af8b Start of WireMock 2019-08-30 17:07:17 -07:00
Liam Newman
0f7ae3cda7 Merge pull request #534 from res0nance/https
Swap to HTTPs
2019-08-28 13:24:52 -07:00
Raihaan Shouhell
baf94e56c8 Swap to HTTPs 2019-08-27 10:45:02 +08:00
Paulo Miguel Almeida
905bd1a4c9 Fix typo
Signed-off-by: Paulo Almeida <paulo.miguel.almeida.rodenas@gmail.com>
2019-08-26 12:37:28 +12:00
Paulo Almeida
96bcf24047 Merge branch 'master' of https://github.com/kohsuke/github-api
# Conflicts:
#	pom.xml
2019-08-26 12:31:23 +12:00
Liam Newman
dfe47235cf Update maven.yml 2019-08-23 19:11:16 -07:00
Liam Newman
b82ea8eaa8 Merge pull request #533 from sullis/jackson-2.9.9.3
jackson-databind 2.9.9.3
2019-08-23 19:06:25 -07:00
Liam Newman
b1b830c268 Switch to spotbugs 2019-08-23 19:02:14 -07:00
Liam Newman
e654d4a6df Fix pom warnings 2019-08-23 18:48:49 -07:00
Liam Newman
ac30b17ecb Do no run GMaven on this project 2019-08-23 18:45:03 -07:00
Liam Newman
95efdb3a51 Use newer dependency plugin 2019-08-23 18:35:38 -07:00
Liam Newman
49c165e203 Update maven.yml 2019-08-23 18:24:52 -07:00
Liam Newman
a4be351d9f Update maven.yml 2019-08-23 18:20:36 -07:00
Liam Newman
3d0401aecd Update maven.yml 2019-08-23 18:17:34 -07:00
Liam Newman
7c27572a53 Split out dependency downloading to new step
For visualization, it helps to not have to search through all the dependency downloads
2019-08-23 18:17:17 -07:00
Liam Newman
1e7760012e Merge pull request #476 from turbanoff/patch-1
Provide more exception details
2019-08-23 18:12:34 -07:00
Liam Newman
24d464b6e5 Add github build action
This ensures that PR's at least build
Currently runs no tests, since they all depend on having user level access to github
2019-08-23 18:10:38 -07:00
Sean Sullivan
499d91f9f8 jackson-databind 2.9.9.3 2019-08-15 15:23:42 -04:00
Matt Farmer
8e0ceaa06b Add a test for requesting reviewers 2019-08-10 20:52:55 -04:00
Matt Farmer
4e62641f7e Add ability to get requested teams 2019-08-10 20:46:34 -04:00
Matt Farmer
688644f5a4 Add support for requesting teams review prs 2019-08-10 20:31:15 -04:00
Paulo Miguel Almeida
4703f2d1f5 Add tests for GithubApp integration;
Add wiremock-standalone library;

Signed-off-by: Paulo Almeida <paulo.miguel.almeida.rodenas@gmail.com>
2019-08-10 19:01:12 +12:00
Artem V. Navrotskiy
14149ae949 Add GitHub API requests logging 2019-07-19 12:00:48 +03:00
Wouter Gerarts
a0fb0d170c Remove unnessesairy "throws"
All IOExceptions are already caught within the method itself.
2019-07-12 17:46:34 +02:00
Vincent Behar
e133afec86 Add support for draft pull requests
See https://developer.github.com/v3/pulls/#input
and https://help.github.com/en/articles/about-pull-requests#draft-pull-requests

Note that it requires the use of a github api preview: https://developer.github.com/v3/previews/#draft-pull-requests
2019-07-11 17:12:20 +02:00
Liam Newman
3ae8ee8ddb Merge pull request #498 from rmetzger/fix-450
Add GHPullRequestReview.submitted_at field
2019-07-01 10:32:01 -07:00
Liam Newman
012643a231 Merge pull request #413 from ThomasCookOnline/fix_version
fix issues
2019-06-19 17:11:59 -07:00
Liam Newman
dccb43f4dc Merge pull request #517 from jamesatha/repo-by-id
Adds the ability to get a repository by ID
2019-06-19 17:11:03 -07:00
Paulo Almeida
15b3bc6a63 Remove JWT dependencies used for testing purposes 2019-06-18 13:36:00 +12:00
Paulo Almeida
2d15bef76d Add missing CHECK_SUITE github event 2019-06-18 11:24:59 +12:00
Paulo Almeida
756d298f04 Add missing INTEGRATION_INSTALLATION_REPOSITORIES github event 2019-06-18 10:50:08 +12:00
Paulo Almeida
9f35eb1a85 Add @Preview and @Deprecated annotations to methods in which the API is still in preview 2019-06-12 11:32:03 +12:00
Paulo Almeida
c905bb4b6c Implement GitHub App API methods 2019-06-11 17:27:07 +12:00
Austin Witt
c78af01c8f Added two getUserPublicOrganizations(...) methods to get public Org memberships of any user, not just the currently-authenticated one. 2019-05-23 09:08:18 -05:00
Austin Witt
084855645a Due-diligence & hygiene updates to GitHub.java 2019-05-23 09:03:47 -05:00
Liam Newman
afce9ece89 Merge pull request #507 from ingwarsw/add_get_team_by_id
Add getTeam by id function
2019-05-22 15:22:25 -07:00
Liam Newman
154e50e36d Merge pull request #499 from anatolyD/feature/let-create-pr-to-org-fork
Create PR from original repo to private org fork
2019-05-22 14:55:52 -07:00
Liam Newman
80a129102b Merge pull request #492 from arykov/fix_add_team_member_role_capital
fixed membership role problem with case
2019-05-17 14:03:43 -07:00
Liam Newman
93672a074e Merge pull request #508 from blacelle/mindthecode-2019-03-24
Update maven dependency
2019-05-16 19:32:04 -07:00
Liam Newman
c7f6f6233c Merge pull request #485 from scotty-g/remove-console-logging
remove system.out from listOrgs
2019-05-16 18:56:45 -07:00
Liam Newman
68915a9daf Added tests for createLabel() method 2019-05-16 18:51:44 -07:00
Liam Newman
13eb91f8dd Preserve api compatibility for createLabel() 2019-05-16 18:44:39 -07:00
Liam Newman
1a8355e6fb Merge branch 'master' into fix_version 2019-05-16 18:23:59 -07:00
James Athappilly
aa2b7ae60a Adds the ability to get a repository by ID
Fixes: https://github.com/kohsuke/github-api/issues/515
2019-04-26 00:29:26 -07:00
Benoit Lacelle
acd36b7ea5 Update maven dependency versions 2019-03-24 12:55:40 +00:00
Karol Lassak
87245ab79f Add getTeam by id function 2019-03-18 14:15:29 +01:00
Long Nguyen
13b6a17827 Added equals and hashcode 2019-03-07 01:08:56 +01:00
Anatoly Danilov
615e4cf24e Create PR is possible without the owner of the repo to modify PR.
Use case: when fork is done into private organization then the original repo maintainer can't have any access there hence this field has to be set to `false` explicitly
2019-02-20 09:25:35 +03:00
Robert Metzger
0e6d08f027 Add GHPullRequestReview.submitted_at field 2019-02-19 10:13:21 +01:00
Alex Rykov
d593e584dd fixed membership role problem with case 2019-02-01 12:19:28 -05:00
sg012265
e046b97160 remove system.out from listOrgs 2018-12-22 21:31:33 -06:00
Martin van Zijl
567d3dac55 Add support for editing Gists.
Fixes issue #466

NOTE: I could not get the deleteFile() method to work.
2018-12-20 08:16:25 +13:00
Martin van Zijl
a67a0aa924 Add method to invite user to organization.
Fixes issue #467
2018-12-14 07:18:29 +13:00
Турбанов Андрей
1b1e3e88fe Provide more exception details
For now if invalid credentials used to search github-api throws following exception

    Exception in thread "main" org.kohsuke.github.GHException: Failed to retrieve https://api.github.com/search/repositories?q=vk+language%3Ajava+created%3A2015-11-26..2016-11-26
	at org.kohsuke.github.Requester$PagingIterator.fetch(Requester.java:529)
	at org.kohsuke.github.Requester$PagingIterator.hasNext(Requester.java:494)
	at org.kohsuke.github.PagedSearchIterable$1.hasNext(PagedSearchIterable.java:55)
	at org.kohsuke.github.PagedIterator.fetch(PagedIterator.java:44)
	at org.kohsuke.github.PagedIterator.hasNext(PagedIterator.java:32)

There is no mentions if credentials at all. Better to propagate exception to user to be able to deal with it.
2018-11-26 01:21:28 +03:00
Immanuel Washington
ec99636ef0 Adding Label description property
Label in the GitHub API has an optional field description which had not been implemented.
2018-11-25 02:10:06 -05:00
Martin van Zijl
9d955d252a Add statistics API.
Fixes issue #330
2018-11-16 18:24:30 +13:00
Martin van Zijl
f136f6837a Added description field to GHTeam class.
Fixes issue #460.
2018-11-13 07:37:07 +13:00
Martin van Zijl
6fc1fb0966 Added a method to list authorizations.
Fixes issue #459
2018-11-12 17:50:49 +13:00
Kohsuke Kawaguchi
fad203a66d [maven-release-plugin] prepare for next development iteration 2018-11-06 08:42:28 -08:00
Kohsuke Kawaguchi
c1bab63ebd [maven-release-plugin] prepare release github-api-1.95 2018-11-06 08:42:18 -08:00
Kohsuke Kawaguchi
40f012b03c rtyler no longer has 50 people he follows 2018-11-06 08:35:48 -08:00
Kohsuke Kawaguchi
a380059389 Merge branch 'master' of github.com:kohsuke/github-api 2018-11-06 08:16:06 -08:00
Kohsuke Kawaguchi
24b998ba2d Merge pull request #461 2018-11-06 08:15:11 -08:00
Kohsuke Kawaguchi
9a1bb09c9f Massaging the changes.
In particular, avoid the kind of addLabel() method that has lots of side
effect and do multiple things.
2018-11-06 08:14:12 -08:00
Kohsuke Kawaguchi
3ad66f8937 Merge pull request #468 from KostyaSha/fixMemLeak
Fix memory leak.
2018-11-06 07:56:15 -08:00
Kohsuke Kawaguchi
a6f3e7df55 Merge pull request #464 2018-11-06 07:49:17 -08:00
Kohsuke Kawaguchi
9345d3be31 Follow the convention in this library 2018-11-06 07:49:02 -08:00
Kohsuke Kawaguchi
8e85bf8839 Merge pull request #470 from recena/archived-attr
Added archived attribute in GHRepository
2018-10-29 08:28:00 -07:00
Manuel Recena
1012dcd194 Added archived attribute in GHRepository. Updated the parent POM 2018-10-25 11:24:46 +02:00
Kanstantsin Shautsou
70251ea11e Fix memory leak.
While repository object is active and code requests commits they are stored in Map.
GHCommit.files contains huge String[]/char[]  amount of data.
The same could be applied to Milestones.
2018-10-20 19:13:47 +03:00
I329802 (Xeric)
9381471fbd add request reviewers as attribute of GHPullRequest 2018-10-11 17:30:25 +08:00
Even Holthe
1c4b716f1a Add methods for adding/removing labels to GHIssue
Fixes #456
2018-10-01 23:29:15 +02:00
Kohsuke Kawaguchi
c8b0584127 [maven-release-plugin] prepare for next development iteration 2018-08-29 21:05:31 -07:00
Kohsuke Kawaguchi
5194a361f4 [maven-release-plugin] prepare release github-api-1.94 2018-08-29 21:05:21 -07:00
Kohsuke Kawaguchi
c44e5d2a87 findbugs fix 2018-08-29 21:00:24 -07:00
Kohsuke Kawaguchi
ee4d514b66 close an opened stream 2018-08-29 20:48:44 -07:00
Kohsuke Kawaguchi
863995cb50 findbugs warning fix 2018-08-29 20:48:36 -07:00
Kohsuke Kawaguchi
cbfe72a76e Fixed a broken test 2018-08-29 20:31:44 -07:00
Kohsuke Kawaguchi
4f17d3519c Merge pull request #411 from tadfisher/master
Add GHRepository.getRelease and GHRepository.getReleaseByTagName
2018-08-30 05:22:26 +02:00
Kohsuke Kawaguchi
3cfcad76ac Merge pull request #417 from twcurrie/tcurrie/revisions
Added release payload.
2018-08-30 05:21:24 +02:00
Kohsuke Kawaguchi
1ca6535811 Merge pull request #449 from martinvanzijl/issue_426_fix_nullptr_when_deleting_refs
Fix for issue #426. Fix null pointer when deleting refs.
2018-08-30 05:21:09 +02:00
Kohsuke Kawaguchi
53612ad2e4 Merge pull request #446 from daniel-beck/fix-page-size
Fix pagination for APIs that supported it ad hoc
2018-08-30 05:20:53 +02:00
Kohsuke Kawaguchi
4b799d264c Merge pull request #443 from Arrow768/GHEventPayload_Issue
Adds the GHEventPayload.Issue class
2018-08-30 05:20:26 +02:00
Kohsuke Kawaguchi
ca5594703a Merge pull request #439 from l3ender/master
Add support for repository searching by "topic"
2018-08-30 05:20:03 +02:00
Kohsuke Kawaguchi
7fc2d9dcca Merge remote-tracking branch 'origin/master' 2018-08-29 20:19:14 -07:00
Kohsuke Kawaguchi
c413fc1e30 Merge pull request #438 from jgangemi/jae/issue-434
- added overloaded 'uploadAsset' method
2018-08-30 05:18:51 +02:00
Kohsuke Kawaguchi
b5086c7759 Merge pull request #437 2018-08-29 20:18:21 -07:00
Kohsuke Kawaguchi
92a015ca4d Clear up import statements 2018-08-29 20:18:10 -07:00
Kohsuke Kawaguchi
3b2802e36d minor doc improvement 2018-08-29 20:18:00 -07:00
Kohsuke Kawaguchi
7bf23eaa15 Merge pull request #436 from jgangemi/jae/rm-exception
- remove unthrown IOException
2018-08-30 05:16:28 +02:00
Kohsuke Kawaguchi
9afd1c5ee8 Merge pull request #435 2018-08-29 20:15:08 -07:00
Kohsuke Kawaguchi
5e36377b36 It appears LOKI preview is done and all those methods are now final 2018-08-29 20:15:01 -07:00
Kohsuke Kawaguchi
c988df13a8 Use a short form 2018-08-29 20:15:01 -07:00
Kohsuke Kawaguchi
29a40d31b7 TAB -> space 2018-08-29 20:15:01 -07:00
Kohsuke Kawaguchi
ddc27e818b Let's not yet expose this new class because it's not final 2018-08-29 20:15:01 -07:00
Kohsuke Kawaguchi
3fa70ac841 doc improvement 2018-08-29 19:05:56 -07:00
Kohsuke Kawaguchi
b2b7dfaf37 Massaged the change to match the existing API design convention 2018-08-29 19:05:19 -07:00
Martin van Zijl
c309c2cf13 Fix for issue #426. Fix null pointer when deleting refs. 2018-08-13 12:36:15 +12:00
Martin van Zijl
71304b114a Fix for issue #376. Added issue events API. 2018-08-13 11:44:21 +12:00
Daniel Beck
0ffcbdbd38 Fix pagination for APIs that supported it ad hoc 2018-07-17 11:27:54 +02:00
Werner
e368a17420 Adds the GHEventPayload.Issue class 2018-07-01 12:23:13 +02:00
Sharath
2fcfb2f67d address review comments in supporting updating content with sha 2018-06-12 18:26:20 -07:00
onoguera-ob
f68a85056e Update integration test. 2018-06-12 18:26:20 -07:00
Oliver Noguera
943f47d29d Add sha1 to updateFiles see
https://developer.github.com/v3/repos/contents/#update-a-file
2018-06-12 18:26:20 -07:00
l3ender
fd37a2c466 Add support for repository searching by "topic"
See https://help.github.com/articles/searching-repositories/#search-by-topic
2018-06-06 11:44:46 -05:00
Jae Gangemi
eacdd7afe8 - added overloaded 'uploadAsset' method 2018-05-30 08:18:25 -06:00
Rechi
fe5ea52cdf [feature] implement Repository Invitations API
fixes #374
2018-05-29 22:00:00 +02:00
Jae Gangemi
ca6d77cbb3 - remove unthrown IOException 2018-05-28 17:49:21 -06:00
Jae Gangemi
1145941d11 - add support for signed commits
- add support for required number of reviews
2018-05-27 15:33:58 -06:00
Kohsuke Kawaguchi
d61697a152 [maven-release-plugin] prepare for next development iteration 2018-05-01 07:56:38 -07:00
Kohsuke Kawaguchi
38b77a9c79 [maven-release-plugin] prepare release github-api-1.93 2018-05-01 07:56:27 -07:00
Kohsuke Kawaguchi
7d294ee8c2 Looks like release rollback didn't quite complete 2018-05-01 07:26:09 -07:00
Kohsuke Kawaguchi
33d9422d03 Merge pull request #422 from ggrell/fix-421-enum-case-issue
Fixes #421 - Enum case doesn't match for Pull Request Reviews
2018-05-01 07:19:42 -07:00
Kohsuke Kawaguchi
bb7302c23a Merge branch 'master' of github.com:kohsuke/github-api 2018-05-01 07:18:57 -07:00
Kohsuke Kawaguchi
d50ae63a5a Merge pull request #431 from Rechi/fixPRLabels
[fix] fetch labels with HTTP GET method
2018-05-01 07:18:43 -07:00
Kohsuke Kawaguchi
1961836e19 Merge pull request #427 from itepikin-smartling/master
Add support for previous_filename for file details in PR.
2018-05-01 07:17:32 -07:00
Kohsuke Kawaguchi
f2ed7c15ce Looks like the permission scheme changed on jenkinsci/violations-plugin 2018-05-01 07:12:30 -07:00
Kohsuke Kawaguchi
4dce173630 Extracted the List<GHUser>->List<String> out to Requester for reuse 2018-05-01 07:03:53 -07:00
Kohsuke Kawaguchi
86f868b2d4 Fixed compilation errors introduced by 8b38a20c18 2018-05-01 06:59:03 -07:00
Kohsuke Kawaguchi
363064f5c0 Merge branch 'master' of github.com:kohsuke/github-api 2018-04-30 19:58:33 -07:00
Kohsuke Kawaguchi
9d99ee9cfc Merge pull request #430 from twcurrie/tcurrie/requestReviewer
Added request reviewers function within GHPullRequest.
2018-04-30 19:58:19 -07:00
Rechi
db8969707d [fix] fetch labels with HTTP GET method 2018-04-06 10:00:00 +02:00
Trevor Currie
a24ac37dfd Added request reviewers function within GHPullRequest. 2018-03-28 23:33:08 -07:00
itepikin
1b04d471b3 Added support for previous_filename for file details in PR. 2018-03-22 11:16:09 +03:00
Gyuri Grell
9cc400a081 Fixes #421 - Enum case doesn't match for Pull Request Reviews
* Set Jackson to ignore case differences in enums.
2018-03-01 20:50:00 -05:00
Kohsuke Kawaguchi
e233aeec0c Merge pull request #410 from Limess/409/update-commons-lang
Update commons-lang to 3.7
2018-03-01 09:45:15 -08:00
Kohsuke Kawaguchi
5dfd621900 Merge pull request #420 from randomvariable/fix/tlsv12
OkHttpConnector: Enforce use of TLSv1.2 to match current Github and Github Enterprise TLS support.
2018-03-01 09:43:24 -08:00
Naadir Jeewa
f0f6a9988f OkHttpConnector: Enforce use of TLSv1.2 to match current Github
and Github Enterprise TLS support.
2018-02-28 09:36:15 +00:00
Trevor Currie
587438938c Added release payload. 2018-02-22 09:38:25 -08:00
Edem Osmanov
2497ac68d1 fix issues 2018-02-14 12:16:01 +02:00
Tad Fisher
75918c59cc Add GHRepository.getRelease and GHRepository.getReleaseByTagName
These implement the API endpoints for:

- GET /repos/:owner/:repo/releases/:id
- GET /repos/:owner/:repo/releases/tags/:tag
2018-02-05 14:30:24 -08:00
Charlie Briggs
8b38a20c18 Update commons-lang to 3.7
This fixes the vulnerabilities:
* https://issues.apache.org/jira/browse/LANG-1373
* https://issues.apache.org/jira/browse/LANG-805.
2018-01-23 11:00:58 +00:00
Kohsuke Kawaguchi
e7b76bfdc5 Doc improvements 2018-01-21 11:51:04 -08:00
Kohsuke Kawaguchi
3503ff6d36 Additional methods for issue comment 2018-01-21 11:50:22 -08:00
Kohsuke Kawaguchi
192e21a9fc [maven-release-plugin] prepare for next development iteration 2018-01-13 11:52:05 -08:00
2282 changed files with 980188 additions and 3968 deletions

29
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@@ -0,0 +1,29 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Desktop (please complete the following information):**
- OS: [e.g. iOS]
- Browser [e.g. chrome, safari]
- Version [e.g. 22]
**Additional context**
Add any other context about the problem here.

10
.github/PULL_REQUEST_TEMPLATE.md vendored Normal file
View File

@@ -0,0 +1,10 @@
# Description
** Describe your change here**
# Before submitting a PR:
We love getting PRs, but we hate asking people for the same basic changes every time.
- [ ] Push your changes to a branch other than `master`. Create your PR from that branch.
- [ ] Add JavaDocs and other comments
- [ ] Write tests that run and pass in CI. See [CONTRIBUTING.md](CONTRIBUTING.md) for details on how to capture snapshot data.
- [ ] Run `mvn install site` locally. This may reformat your code, commit those changes. If this command doesn't succeed, your change will not pass CI.

19
.github/release-drafter.yml vendored Normal file
View File

@@ -0,0 +1,19 @@
name-template: 'v$NEXT_PATCH_VERSION 🌈'
tag-template: 'v$NEXT_PATCH_VERSION'
categories:
- title: '🚀 Features'
labels:
- 'feature'
- 'enhancement'
- title: '🐛 Bug Fixes'
labels:
- 'fix'
- 'bugfix'
- 'bug'
- title: '🧰 Maintenance'
label: 'chore'
change-template: '- $TITLE @$AUTHOR (#$NUMBER)'
template: |
## Changes
$CHANGES

22
.github/workflows/maven-build.yml vendored Normal file
View File

@@ -0,0 +1,22 @@
name: Java CI Build and Test
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
java: [ '1.8.0', '11.0.x', '13.0.x' ]
steps:
- uses: actions/checkout@v1
- name: Set up JDK
uses: actions/setup-java@v1
with:
java-version: ${{ matrix.java }}
- name: Maven Download all dependencies
run: mvn -B org.apache.maven.plugins:maven-dependency-plugin:3.1.1:go-offline
- name: Maven Build
run: mvn -B install site -P ci --file pom.xml

1174
CHANGELOG.md Normal file

File diff suppressed because it is too large Load Diff

76
CODE_OF_CONDUCT.md Normal file
View File

@@ -0,0 +1,76 @@
# Contributor Covenant Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, sex characteristics, gender identity and expression,
level of experience, education, socio-economic status, nationality, personal
appearance, race, religion, or sexual identity and orientation.
## Our Standards
Examples of behavior that contributes to creating a positive environment
include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or
advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.
## Scope
This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at bitwiseman@gmail.com. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see
https://www.contributor-covenant.org/faq

62
CONTRIBUTING.md Normal file
View File

@@ -0,0 +1,62 @@
# Contributing
## Using WireMock and Snapshots
This project has started converting to using WireMock to stub out http responses instead of use live data.
This change will allow tests to run in a CI environment without needing to touch github.com.
The tests will instead serve previously recorded responses from local data files.
### Running WireMock tests
Example:
`mvn install -Dtest=WireMockStatusReporterTest`
This the default behavior.
### Setting up credential
1. Create an OAuth token on github.com
2. Set the GITHUB_OAUTH environment variable to the value of that token
3. Set the system property `test.github.useProxy` (usually like "-Dtest.github.useProxy" as a Java VM option)
`mvn install -Dtest.github.useProxy -Dtest=WireMockStatusReporterTest`
4. The above should report no test failures and include the following console output:
`WireMockStatusReporterTest: GitHub proxying and user auth correctly configured for user login: <your login>`
Whenever you run tests with `-Dtest.github.useProxy`, they will try to get data from local files but will fallback to proxying to github if not found.
### Writing a new test
Once you have credentials setup, you add new test classes and test methods as you would normally.
Keep `useProxy` enabled and iterate on your tests as needed. Remember, while proxying your tests are interacting with GitHub - you will need to clean up your state between runs.
When you are ready to create a snapshot of your test data,
run your test with `test.github.takeSnapshot` ("-Dtest.github.takeSnapshot" as a Java VM option). For example:
`mvn install -Dtest.github.takeSnapshot -Dtest=YourTestClassName`
The above command would create snapshot WireMock data files under the path `src/test/resources/org/kohsuhke/github/YourTestClassName/wiremock`.
Each method would get a separate director that would hold the data files for that test method.
Add all files including the generated data to your commit and submit a PR.
### Modifying existing tests
When modifying existing tests, you can change the stubbed WireMock data files by hand or you can try generating a new snapshot.
#### Manual editing of data (minor changes only)
If you know what data will change, it is sometimes simplest to make any required changes to the data files manually.
This can be easier if the changes are minor or when you development environment is not setup to to take updated snapshots.
#### Generating a new snapshot
For more most changes, it is recommended to take a new snapshot when updating tests.
Delete the wiremock data files for the test method you will be modifying.
For more significant changes, you can even delete the WireMock files for an entire test class.
Then follow the same as when writing a new test: run with proxy enabled to debug, take a new snapshot when done, commit everything, and submit the PR.

3
README
View File

@@ -1,3 +0,0 @@
Java API for GitHub
See http://github-api.kohsuke.org/ for more details

7
README.md Normal file
View File

@@ -0,0 +1,7 @@
# Java API for GitHub
[![Sonatype Nexus (Releases)](https://img.shields.io/nexus/r/org.kohsuke/github-api?server=https%3A%2F%2Foss.sonatype.org)](https://mvnrepository.com/artifact/org.kohsuke/github-api)
[![Join the chat at https://gitter.im/github-api/github-api](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/github-api/github-api?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
See https://github-api.kohsuke.org/ for more details

433
pom.xml
View File

@@ -3,57 +3,151 @@
<parent>
<groupId>org.kohsuke</groupId>
<artifactId>pom</artifactId>
<version>17</version>
<version>21</version>
<relativePath />
</parent>
<artifactId>github-api</artifactId>
<version>1.92</version>
<version>1.101</version>
<name>GitHub API for Java</name>
<url>http://github-api.kohsuke.org/</url>
<url>https://github-api.kohsuke.org/</url>
<description>GitHub API for Java</description>
<scm>
<connection>scm:git:git@github.com/kohsuke/${project.artifactId}.git</connection>
<developerConnection>scm:git:ssh://git@github.com/kohsuke/${project.artifactId}.git</developerConnection>
<url>http://${project.artifactId}.kohsuke.org/</url>
<tag>github-api-1.92</tag>
<connection>scm:git:git@github.com/github-api/${project.artifactId}.git</connection>
<developerConnection>scm:git:ssh://git@github.com/github-api/${project.artifactId}.git</developerConnection>
<url>https://${project.artifactId}.kohsuke.org/</url>
<tag>github-api-1.101</tag>
</scm>
<distributionManagement>
<site>
<id>github-pages</id>
<url>gitsite:git@github.com/kohsuke/${project.artifactId}.git</url>
<url>gitsite:git@github.com/github-api/${project.artifactId}.git</url>
</site>
</distributionManagement>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<findbugs-maven-plugin.version>3.0.2</findbugs-maven-plugin.version>
<findbugs-maven-plugin.failOnError>true</findbugs-maven-plugin.failOnError>
<spotbugs-maven-plugin.version>3.1.12.2</spotbugs-maven-plugin.version>
<spotbugs.version>3.1.12</spotbugs.version>
<spotbugs-maven-plugin.failOnError>true</spotbugs-maven-plugin.failOnError>
<hamcrest.version>2.2</hamcrest.version>
<okhttp3.version>4.2.2</okhttp3.version>
<okio.version>2.4.1</okio.version>
<formatter-maven-plugin.goal>format</formatter-maven-plugin.goal>
<impsort-maven-plugin.goal>sort</impsort-maven-plugin.goal>
<jacoco.coverage.target.class>.80</jacoco.coverage.target.class>
<jacoco.coverage.target.method>0.20</jacoco.coverage.target.method>
<jacoco.coverage.target.line>0.50</jacoco.coverage.target.line>
<jacoco.coverage.target.other>0.50</jacoco.coverage.target.other>
<!-- For non-ci builds we'd like the build to still complete if jacoco metrics aren't met. -->
<jacoco.haltOnFailure>false</jacoco.haltOnFailure>
</properties>
<build>
<extensions>
<extension>
<groupId>org.apache.maven.scm</groupId>
<artifactId>maven-scm-provider-gitexe</artifactId>
<version>1.11.2</version>
</extension>
<extension>
<groupId>org.apache.maven.scm</groupId>
<artifactId>maven-scm-manager-plexus</artifactId>
<version>1.11.2</version>
</extension>
</extensions>
<testResources>
<testResource>
<directory>src/test/resources</directory>
<excludes>
<exclude>**/wiremock/**</exclude>
</excludes>
</testResource>
</testResources>
<pluginManagement>
<plugins>
<!-- adds jacoco coverage -->
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.5</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.1.1</version>
<configuration>
<source>8</source>
<failOnWarnings>true</failOnWarnings>
</configuration>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-site-plugin</artifactId>
<version>3.8.2</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<version>2.5.3</version>
<configuration>
<rerunFailingTestsCount>2</rerunFailingTestsCount>
<autoVersionSubmodules>true</autoVersionSubmodules>
<useReleaseProfile>false</useReleaseProfile>
<releaseProfiles>release</releaseProfiles>
<goals>deploy</goals>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-project-info-reports-plugin</artifactId>
<version>3.0.0</version>
<dependencies>
<dependency>
<groupId>org.apache.bcel</groupId>
<artifactId>bcel</artifactId>
<version>6.4.1</version>
</dependency>
</dependencies>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<annotationProcessorPaths>
<annotationProcessorPath>
<groupId>org.jenkins-ci</groupId>
<artifactId>annotation-indexer</artifactId>
<version>1.12</version>
</annotationProcessorPath>
</annotationProcessorPaths>
</configuration>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.2</version>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>animal-sniffer-maven-plugin</artifactId>
<version>1.15</version>
<version>1.18</version>
<configuration>
<signature>
<groupId>org.codehaus.mojo.signature</groupId>
<artifactId>java15</artifactId>
<artifactId>java18</artifactId>
<version>1.0</version>
</signature>
</configuration>
<executions>
<execution>
<id>ensure-java-1.5-class-library</id>
<id>ensure-java-1.8-class-library</id>
<phase>test</phase>
<goals>
<goal>check</goal>
@@ -74,19 +168,70 @@
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>findbugs-maven-plugin</artifactId>
<version>${findbugs-maven-plugin.version}</version>
<groupId>net.revelc.code.formatter</groupId>
<artifactId>formatter-maven-plugin</artifactId>
<version>2.11.0</version>
<executions>
<execution>
<goals>
<goal>${formatter-maven-plugin.goal}</goal>
</goals>
<configuration>
<configFile>src/main/resources/eclipse/formatter.xml</configFile>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>net.revelc.code</groupId>
<artifactId>impsort-maven-plugin</artifactId>
<version>1.3.2</version>
<configuration>
<xmlOutput>true</xmlOutput>
<failOnError>${findbugs-maven-plugin.failOnError}</failOnError>
<groups>*,java.,javax.</groups>
<removeUnused>true</removeUnused>
<staticAfter>true</staticAfter>
</configuration>
<executions>
<execution>
<id>run-findbugs</id>
<phase>verify</phase>
<goals>
<goal>check</goal>
<goal>${impsort-maven-plugin.goal}</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.github.spotbugs</groupId>
<artifactId>spotbugs-maven-plugin</artifactId>
<version>${spotbugs-maven-plugin.version}</version>
<configuration>
<xmlOutput>true</xmlOutput>
<failOnError>${spotbugs-maven-plugin.failOnError}</failOnError>
</configuration>
<executions>
<execution>
<id>run-spotbugs</id>
<phase>verify</phase>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
<dependencies>
<!-- overwrite dependency on spotbugs if you want to specify the version of spotbugs -->
<dependency>
<groupId>com.github.spotbugs</groupId>
<artifactId>spotbugs</artifactId>
<version>${spotbugs.version}</version>
</dependency>
</dependencies>
</plugin>
<!-- Do not use gmaven plugin -->
<plugin>
<groupId>org.codehaus.gmaven</groupId>
<artifactId>gmaven-plugin</artifactId>
<executions>
<execution>
<goals>
</goals>
</execution>
</executions>
@@ -96,14 +241,33 @@
<dependencies>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.9</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.7</version>
<version>1.13</version>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest</artifactId>
<version>${hamcrest.version}</version>
<scope>test</scope>
</dependency>
<!-- This is needed in order to force junit4 and JTH tests to use newer hamcrest version -->
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-core</artifactId>
<version>${hamcrest.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-library</artifactId>
<version>${hamcrest.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
@@ -111,26 +275,20 @@
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-all</artifactId>
<version>1.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.2</version>
<version>2.10.1</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>1.4</version>
<version>2.6</version>
</dependency>
<dependency>
<groupId>com.infradna.tool</groupId>
<artifactId>bridge-method-annotation</artifactId>
<version>1.17</version>
<version>1.18</version>
<optional>true</optional>
</dependency>
<dependency>
@@ -142,21 +300,35 @@
<dependency>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit</artifactId>
<version>4.9.0.201710071750-r</version>
<version>5.5.1.201910021850-r</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.squareup.okio</groupId>
<artifactId>okio</artifactId>
<version>${okio.version}</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>${okhttp3.version}</version>
<optional>true</optional>
</dependency>
<!-- This is the last version of okhttp3 that support UrlConnection -->
<!-- The class using this has been deprecated, this dependency can be remove when that class is. -->
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp-urlconnection</artifactId>
<version>3.12.3</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.squareup.okhttp</groupId>
<artifactId>okhttp-urlconnection</artifactId>
<version>2.7.5</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp-urlconnection</artifactId>
<version>3.9.0</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.kohsuke</groupId>
<artifactId>wordnet-random-name</artifactId>
@@ -165,43 +337,198 @@
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>1.10.19</version>
<artifactId>mockito-core</artifactId>
<version>3.1.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>annotations</artifactId>
<version>3.0.1</version>
<scope>provided</scope>
<groupId>com.github.spotbugs</groupId>
<artifactId>spotbugs-annotations</artifactId>
<version>${spotbugs.version}</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.github.tomakehurst</groupId>
<artifactId>wiremock-jre8-standalone</artifactId>
<version>2.25.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.6</version>
<scope>test</scope>
</dependency>
</dependencies>
<repositories>
<repository>
<id>repo.jenkins-ci.org</id>
<url>http://repo.jenkins-ci.org/public/</url>
<url>https://repo.jenkins-ci.org/public/</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>repo.jenkins-ci.org</id>
<url>http://repo.jenkins-ci.org/public/</url>
<url>https://repo.jenkins-ci.org/public/</url>
</pluginRepository>
</pluginRepositories>
<profiles>
<profile>
<id>ci</id>
<properties>
<formatter-maven-plugin.goal>validate</formatter-maven-plugin.goal>
<impsort-maven-plugin.goal>check</impsort-maven-plugin.goal>
</properties>
<build>
</build>
</profile>
<profile>
<id>jacoco</id>
<activation>
<property>
<name>enable-jacoco</name>
</property>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.5</version>
<executions>
<execution>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<!-- attached to Maven test phase -->
<execution>
<id>report</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
<execution>
<id>check</id>
<phase>install</phase>
<goals>
<goal>check</goal>
</goals>
<configuration>
<rules>
<rule>
<!--We end up with chatty logs, but it shows us which particular classes -->
<!--are lacking in coverage. If this is too much, just remove the -->
<!--<element>CLASS</element> tag below. -->
<element>CLASS</element>
<limits>
<!-- These limits can be overridden, in the form of `0.50` for -->
<!-- 50%, as necessary. Using a property just puts it in one spot. -->
<!--
<limit>
<counter>LINE</counter>
<value>COVEREDRATIO</value>
<minimum>${jacoco.coverage.target.lines}</minimum>
</limit>
-->
<!--
<limit>
<counter>BRANCH</counter>
<value>COVEREDRATIO</value>
<minimum>${jacoco.coverage.target.other}</minimum>
</limit>
-->
<!--
<limit>
<counter>INSTRUCTION</counter>
<value>COVEREDRATIO</value>
<minimum>${jacoco.coverage.target.other}</minimum>
</limit>
-->
<!--
<limit>
<counter>COMPLEXITY</counter>
<value>COVEREDRATIO</value>
<minimum>${jacoco.coverage.target.other}</minimum>
</limit>
-->
<limit>
<counter>METHOD</counter>
<value>COVEREDRATIO</value>
<minimum>${jacoco.coverage.target.method}</minimum>
</limit>
<!-- <limit>-->
<!-- <counter>CLASS</counter>-->
<!-- <value>COVEREDRATIO</value>-->
<!-- <minimum>${jacoco.coverage.target.class}</minimum>-->
<!-- </limit>-->
</limits>
<excludes>
<exclude>org.kohsuke.github.extras.okhttp3.ObsoleteUrlFactory.**</exclude>
<exclude>org.kohsuke.github.extras.okhttp3.ObsoleteUrlFactory</exclude>
<exclude>org.kohsuke.github.extras.OkHttp3Connector</exclude>
<!--<exclude>io.jenkins.plugins.todeclarative.converter.api.*</exclude>-->
</excludes>
</rule>
</rules>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>release</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>1.6</version>
<executions>
<execution>
<id>sign-artifacts</id>
<phase>verify</phase>
<goals>
<goal>sign</goal>
</goals>
<configuration>
<gpgArguments>
<arg>--pinentry-mode</arg>
<arg>loopback</arg>
</gpgArguments>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.2.0</version>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<reporting>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-project-info-reports-plugin</artifactId>
</plugin>
</plugins>
</reporting>
<licenses>
<license>
<name>The MIT license</name>
<url>http://www.opensource.org/licenses/mit-license.php</url>
<url>https://www.opensource.org/licenses/mit-license.php</url>
<distribution>repo</distribution>
</license>
</licenses>

View File

@@ -8,7 +8,7 @@ import java.net.HttpURLConnection;
* Pluggable strategy to determine what to do when the API abuse limit is hit.
*
* @author Kohsuke Kawaguchi
* @see GitHubBuilder#withAbuseLimitHandler(AbuseLimitHandler)
* @see GitHubBuilder#withAbuseLimitHandler(AbuseLimitHandler) GitHubBuilder#withAbuseLimitHandler(AbuseLimitHandler)
* @see <a href="https://developer.github.com/v3/#abuse-rate-limits">documentation</a>
* @see RateLimitHandler
*/
@@ -17,16 +17,18 @@ public abstract class AbuseLimitHandler {
* Called when the library encounters HTTP error indicating that the API abuse limit is reached.
*
* <p>
* Any exception thrown from this method will cause the request to fail, and the caller of github-api
* will receive an exception. If this method returns normally, another request will be attempted.
* For that to make sense, the implementation needs to wait for some time.
* Any exception thrown from this method will cause the request to fail, and the caller of github-api will receive
* an exception. If this method returns normally, another request will be attempted. For that to make sense, the
* implementation needs to wait for some time.
*
* @see <a href="https://developer.github.com/v3/#abuse-rate-limits">API documentation from GitHub</a>
* @param e
* Exception from Java I/O layer. If you decide to fail the processing, you can throw
* this exception (or wrap this exception into another exception and throw it.)
* Exception from Java I/O layer. If you decide to fail the processing, you can throw this exception (or
* wrap this exception into another exception and throw it).
* @param uc
* Connection that resulted in an error. Useful for accessing other response headers.
* Connection that resulted in an error. Useful for accessing other response headers.
* @throws IOException
* on failure
* @see <a href="https://developer.github.com/v3/#abuse-rate-limits">API documentation from GitHub</a>
*/
public abstract void onError(IOException e, HttpURLConnection uc) throws IOException;
@@ -38,16 +40,17 @@ public abstract class AbuseLimitHandler {
public void onError(IOException e, HttpURLConnection uc) throws IOException {
try {
Thread.sleep(parseWaitTime(uc));
} catch (InterruptedException _) {
throw (InterruptedIOException)new InterruptedIOException().initCause(e);
} catch (InterruptedException ex) {
throw (InterruptedIOException) new InterruptedIOException().initCause(e);
}
}
private long parseWaitTime(HttpURLConnection uc) {
String v = uc.getHeaderField("Retry-After");
if (v==null) return 60 * 1000; // can't tell, return 1 min
if (v == null)
return 60 * 1000; // can't tell, return 1 min
return Math.max(1000, Long.parseLong(v)*1000);
return Math.max(1000, Long.parseLong(v) * 1000);
}
};
@@ -57,7 +60,7 @@ public abstract class AbuseLimitHandler {
public static final AbuseLimitHandler FAIL = new AbuseLimitHandler() {
@Override
public void onError(IOException e, HttpURLConnection uc) throws IOException {
throw (IOException)new IOException("Abust limit reached").initCause(e);
throw (IOException) new IOException("Abuse limit reached").initCause(e);
}
};
}

View File

@@ -28,7 +28,7 @@ import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
/**
* @author Kohsuke Kawaguchi
*/
@SuppressFBWarnings(value = "UUF_UNUSED_PUBLIC_OR_PROTECTED_FIELD",
@SuppressFBWarnings(value = "UUF_UNUSED_PUBLIC_OR_PROTECTED_FIELD",
justification = "Being constructed by JSON deserialization")
class DeleteToken {
public String delete_token;

View File

@@ -0,0 +1,274 @@
package org.kohsuke.github;
import java.io.IOException;
import java.net.URL;
import java.util.List;
import java.util.Map;
import static org.kohsuke.github.Previews.MACHINE_MAN;
/**
* A Github App.
*
* @author Paulo Miguel Almeida
* @see GitHub#getApp() GitHub#getApp()
*/
public class GHApp extends GHObject {
private GitHub root;
private GHUser owner;
private String name;
private String description;
private String externalUrl;
private Map<String, String> permissions;
private List<GHEvent> events;
private long installationsCount;
private String htmlUrl;
/**
* Gets owner.
*
* @return the owner
*/
public GHUser getOwner() {
return owner;
}
/**
* Sets owner.
*
* @param owner
* the owner
*/
public void setOwner(GHUser owner) {
this.owner = owner;
}
/**
* Gets name.
*
* @return the name
*/
public String getName() {
return name;
}
/**
* Sets name.
*
* @param name
* the name
*/
public void setName(String name) {
this.name = name;
}
/**
* Gets description.
*
* @return the description
*/
public String getDescription() {
return description;
}
/**
* Sets description.
*
* @param description
* the description
*/
public void setDescription(String description) {
this.description = description;
}
/**
* Gets external url.
*
* @return the external url
*/
public String getExternalUrl() {
return externalUrl;
}
/**
* Sets external url.
*
* @param externalUrl
* the external url
*/
public void setExternalUrl(String externalUrl) {
this.externalUrl = externalUrl;
}
/**
* Gets events.
*
* @return the events
*/
public List<GHEvent> getEvents() {
return events;
}
/**
* Sets events.
*
* @param events
* the events
*/
public void setEvents(List<GHEvent> events) {
this.events = events;
}
/**
* Gets installations count.
*
* @return the installations count
*/
public long getInstallationsCount() {
return installationsCount;
}
/**
* Sets installations count.
*
* @param installationsCount
* the installations count
*/
public void setInstallationsCount(long installationsCount) {
this.installationsCount = installationsCount;
}
public URL getHtmlUrl() {
return GitHub.parseURL(htmlUrl);
}
/**
* Gets permissions.
*
* @return the permissions
*/
public Map<String, String> getPermissions() {
return permissions;
}
/**
* Sets permissions.
*
* @param permissions
* the permissions
*/
public void setPermissions(Map<String, String> permissions) {
this.permissions = permissions;
}
GHApp wrapUp(GitHub root) {
this.root = root;
return this;
}
/**
* Obtains all the installations associated with this app.
* <p>
* You must use a JWT to access this endpoint.
*
* @return a list of App installations
* @see <a href="https://developer.github.com/v3/apps/#list-installations">List installations</a>
*/
@Preview
@Deprecated
public PagedIterable<GHAppInstallation> listInstallations() {
return root.retrieve()
.withPreview(MACHINE_MAN)
.asPagedIterable("/app/installations", GHAppInstallation[].class, item -> item.wrapUp(root));
}
/**
* Obtain an installation associated with this app.
* <p>
* You must use a JWT to access this endpoint.
*
* @param id
* Installation Id
* @return a GHAppInstallation
* @throws IOException
* on error
* @see <a href="https://developer.github.com/v3/apps/#get-an-installation">Get an installation</a>
*/
@Preview
@Deprecated
public GHAppInstallation getInstallationById(long id) throws IOException {
return root.retrieve()
.withPreview(MACHINE_MAN)
.to(String.format("/app/installations/%d", id), GHAppInstallation.class)
.wrapUp(root);
}
/**
* Obtain an organization installation associated with this app.
* <p>
* You must use a JWT to access this endpoint.
*
* @param name
* Organization name
* @return a GHAppInstallation
* @throws IOException
* on error
* @see <a href="https://developer.github.com/v3/apps/#get-an-organization-installation">Get an organization
* installation</a>
*/
@Preview
@Deprecated
public GHAppInstallation getInstallationByOrganization(String name) throws IOException {
return root.retrieve()
.withPreview(MACHINE_MAN)
.to(String.format("/orgs/%s/installation", name), GHAppInstallation.class)
.wrapUp(root);
}
/**
* Obtain an repository installation associated with this app.
* <p>
* You must use a JWT to access this endpoint.
*
* @param ownerName
* Organization or user name
* @param repositoryName
* Repository name
* @return a GHAppInstallation
* @throws IOException
* on error
* @see <a href="https://developer.github.com/v3/apps/#get-a-repository-installation">Get a repository
* installation</a>
*/
@Preview
@Deprecated
public GHAppInstallation getInstallationByRepository(String ownerName, String repositoryName) throws IOException {
return root.retrieve()
.withPreview(MACHINE_MAN)
.to(String.format("/repos/%s/%s/installation", ownerName, repositoryName), GHAppInstallation.class)
.wrapUp(root);
}
/**
* Obtain a user installation associated with this app.
* <p>
* You must use a JWT to access this endpoint.
*
* @param name
* user name
* @return a GHAppInstallation
* @throws IOException
* on error
* @see <a href="https://developer.github.com/v3/apps/#get-a-user-installation">Get a user installation</a>
*/
@Preview
@Deprecated
public GHAppInstallation getInstallationByUser(String name) throws IOException {
return root.retrieve()
.withPreview(MACHINE_MAN)
.to(String.format("/users/%s/installation", name), GHAppInstallation.class)
.wrapUp(root);
}
}

View File

@@ -0,0 +1,72 @@
package org.kohsuke.github;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static org.kohsuke.github.Previews.MACHINE_MAN;
/**
* Creates a access token for a GitHub App Installation
*
* @author Paulo Miguel Almeida
* @see GHAppInstallation#createToken(Map) GHAppInstallation#createToken(Map)
*/
public class GHAppCreateTokenBuilder {
private final GitHub root;
protected final Requester builder;
private final String apiUrlTail;
@Preview
@Deprecated
GHAppCreateTokenBuilder(GitHub root, String apiUrlTail, Map<String, GHPermissionType> permissions) {
this.root = root;
this.apiUrlTail = apiUrlTail;
this.builder = new Requester(root);
withPermissions(builder, permissions);
}
/**
* By default the installation token has access to all repositories that the installation can access. To restrict
* the access to specific repositories, you can provide the repository_ids when creating the token. When you omit
* repository_ids, the response does not contain neither the repositories nor the permissions key.
*
* @param repositoryIds
* Array containing the repositories Ids
* @return a GHAppCreateTokenBuilder
*/
@Preview
@Deprecated
public GHAppCreateTokenBuilder repositoryIds(List<Long> repositoryIds) {
this.builder.with("repository_ids", repositoryIds);
return this;
}
/**
* Creates an app token with all the parameters.
* <p>
* You must use a JWT to access this endpoint.
*
* @return a GHAppInstallationToken
* @throws IOException
* on error
*/
@Preview
@Deprecated
public GHAppInstallationToken create() throws IOException {
return builder.method("POST")
.withPreview(MACHINE_MAN)
.to(apiUrlTail, GHAppInstallationToken.class)
.wrapUp(root);
}
private static Requester withPermissions(Requester builder, Map<String, GHPermissionType> value) {
Map<String, String> retMap = new HashMap<String, String>();
for (Map.Entry<String, GHPermissionType> entry : value.entrySet()) {
retMap.put(entry.getKey(), Requester.transformEnum(entry.getValue()));
}
return builder.with("permissions", retMap);
}
}

View File

@@ -0,0 +1,293 @@
package org.kohsuke.github;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.io.IOException;
import java.net.URL;
import java.util.List;
import java.util.Map;
import static org.kohsuke.github.Previews.GAMBIT;
/**
* A Github App Installation.
*
* @author Paulo Miguel Almeida
* @see GHApp#listInstallations() GHApp#listInstallations()
* @see GHApp#getInstallationById(long) GHApp#getInstallationById(long)
* @see GHApp#getInstallationByOrganization(String) GHApp#getInstallationByOrganization(String)
* @see GHApp#getInstallationByRepository(String, String) GHApp#getInstallationByRepository(String, String)
* @see GHApp#getInstallationByUser(String) GHApp#getInstallationByUser(String)
*/
public class GHAppInstallation extends GHObject {
private GitHub root;
private GHUser account;
@JsonProperty("access_tokens_url")
private String accessTokenUrl;
@JsonProperty("repositories_url")
private String repositoriesUrl;
@JsonProperty("app_id")
private long appId;
@JsonProperty("target_id")
private long targetId;
@JsonProperty("target_type")
private GHTargetType targetType;
private Map<String, GHPermissionType> permissions;
private List<GHEvent> events;
@JsonProperty("single_file_name")
private String singleFileName;
@JsonProperty("repository_selection")
private GHRepositorySelection repositorySelection;
private String htmlUrl;
public URL getHtmlUrl() {
return GitHub.parseURL(htmlUrl);
}
/**
* Gets root.
*
* @return the root
*/
public GitHub getRoot() {
return root;
}
/**
* Sets root.
*
* @param root
* the root
*/
public void setRoot(GitHub root) {
this.root = root;
}
/**
* Gets account.
*
* @return the account
*/
public GHUser getAccount() {
return account;
}
/**
* Sets account.
*
* @param account
* the account
*/
public void setAccount(GHUser account) {
this.account = account;
}
/**
* Gets access token url.
*
* @return the access token url
*/
public String getAccessTokenUrl() {
return accessTokenUrl;
}
/**
* Sets access token url.
*
* @param accessTokenUrl
* the access token url
*/
public void setAccessTokenUrl(String accessTokenUrl) {
this.accessTokenUrl = accessTokenUrl;
}
/**
* Gets repositories url.
*
* @return the repositories url
*/
public String getRepositoriesUrl() {
return repositoriesUrl;
}
/**
* Sets repositories url.
*
* @param repositoriesUrl
* the repositories url
*/
public void setRepositoriesUrl(String repositoriesUrl) {
this.repositoriesUrl = repositoriesUrl;
}
/**
* Gets app id.
*
* @return the app id
*/
public long getAppId() {
return appId;
}
/**
* Sets app id.
*
* @param appId
* the app id
*/
public void setAppId(long appId) {
this.appId = appId;
}
/**
* Gets target id.
*
* @return the target id
*/
public long getTargetId() {
return targetId;
}
/**
* Sets target id.
*
* @param targetId
* the target id
*/
public void setTargetId(long targetId) {
this.targetId = targetId;
}
/**
* Gets target type.
*
* @return the target type
*/
public GHTargetType getTargetType() {
return targetType;
}
/**
* Sets target type.
*
* @param targetType
* the target type
*/
public void setTargetType(GHTargetType targetType) {
this.targetType = targetType;
}
/**
* Gets permissions.
*
* @return the permissions
*/
public Map<String, GHPermissionType> getPermissions() {
return permissions;
}
/**
* Sets permissions.
*
* @param permissions
* the permissions
*/
public void setPermissions(Map<String, GHPermissionType> permissions) {
this.permissions = permissions;
}
/**
* Gets events.
*
* @return the events
*/
public List<GHEvent> getEvents() {
return events;
}
/**
* Sets events.
*
* @param events
* the events
*/
public void setEvents(List<GHEvent> events) {
this.events = events;
}
/**
* Gets single file name.
*
* @return the single file name
*/
public String getSingleFileName() {
return singleFileName;
}
/**
* Sets single file name.
*
* @param singleFileName
* the single file name
*/
public void setSingleFileName(String singleFileName) {
this.singleFileName = singleFileName;
}
/**
* Gets repository selection.
*
* @return the repository selection
*/
public GHRepositorySelection getRepositorySelection() {
return repositorySelection;
}
/**
* Sets repository selection.
*
* @param repositorySelection
* the repository selection
*/
public void setRepositorySelection(GHRepositorySelection repositorySelection) {
this.repositorySelection = repositorySelection;
}
GHAppInstallation wrapUp(GitHub root) {
this.root = root;
return this;
}
/**
* Delete a Github App installation
* <p>
* You must use a JWT to access this endpoint.
*
* @throws IOException
* on error
* @see <a href="https://developer.github.com/v3/apps/#delete-an-installation">Delete an installation</a>
*/
@Preview
@Deprecated
public void deleteInstallation() throws IOException {
root.retrieve().method("DELETE").withPreview(GAMBIT).to(String.format("/app/installations/%d", id));
}
/**
* Starts a builder that creates a new App Installation Token.
*
* <p>
* You use the returned builder to set various properties, then call {@link GHAppCreateTokenBuilder#create()} to
* finally create an access token.
*
* @param permissions
* map of permissions for the created token
* @return a GHAppCreateTokenBuilder on error
*/
@Preview
@Deprecated
public GHAppCreateTokenBuilder createToken(Map<String, GHPermissionType> permissions) {
return new GHAppCreateTokenBuilder(root, String.format("/app/installations/%d/access_tokens", id), permissions);
}
}

View File

@@ -0,0 +1,142 @@
package org.kohsuke.github;
import com.infradna.tool.bridge_method_injector.WithBridgeMethods;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
* A Github App Installation Token.
*
* @author Paulo Miguel Almeida
* @see GHAppInstallation#createToken(Map) GHAppInstallation#createToken(Map)
*/
public class GHAppInstallationToken {
private GitHub root;
private String token;
protected String expires_at;
private Map<String, String> permissions;
private List<GHRepository> repositories;
private GHRepositorySelection repositorySelection;
/**
* Gets root.
*
* @return the root
*/
public GitHub getRoot() {
return root;
}
/**
* Sets root.
*
* @param root
* the root
*/
public void setRoot(GitHub root) {
this.root = root;
}
/**
* Gets permissions.
*
* @return the permissions
*/
public Map<String, String> getPermissions() {
return permissions;
}
/**
* Sets permissions.
*
* @param permissions
* the permissions
*/
public void setPermissions(Map<String, String> permissions) {
this.permissions = permissions;
}
/**
* Gets token.
*
* @return the token
*/
public String getToken() {
return token;
}
/**
* Sets token.
*
* @param token
* the token
*/
public void setToken(String token) {
this.token = token;
}
/**
* Gets repositories.
*
* @return the repositories
*/
public List<GHRepository> getRepositories() {
return repositories;
}
/**
* Sets repositories.
*
* @param repositories
* the repositories
*/
public void setRepositories(List<GHRepository> repositories) {
this.repositories = repositories;
}
/**
* Gets repository selection.
*
* @return the repository selection
*/
public GHRepositorySelection getRepositorySelection() {
return repositorySelection;
}
/**
* Sets repository selection.
*
* @param repositorySelection
* the repository selection
*/
public void setRepositorySelection(GHRepositorySelection repositorySelection) {
this.repositorySelection = repositorySelection;
}
/**
* Gets expires at.
*
* @return date when this token expires
* @throws IOException
* on error
*/
@WithBridgeMethods(value = String.class, adapterMethod = "expiresAtStr")
public Date getExpiresAt() throws IOException {
return GitHub.parseDate(expires_at);
}
@SuppressFBWarnings(value = "UPM_UNCALLED_PRIVATE_METHOD", justification = "Bridge method of getExpiresAt")
private Object expiresAtStr(Date id, Class type) {
return expires_at;
}
GHAppInstallationToken wrapUp(GitHub root) {
this.root = root;
return this;
}
}

View File

@@ -6,7 +6,7 @@ import java.net.URL;
/**
* Asset in a release.
*
* @see GHRelease#getAssets()
* @see GHRelease#getAssets() GHRelease#getAssets()
*/
public class GHAsset extends GHObject {
GitHub root;
@@ -19,44 +19,100 @@ public class GHAsset extends GHObject {
private long download_count;
private String browser_download_url;
/**
* Gets content type.
*
* @return the content type
*/
public String getContentType() {
return content_type;
}
/**
* Sets content type.
*
* @param contentType
* the content type
* @throws IOException
* the io exception
*/
public void setContentType(String contentType) throws IOException {
edit("content_type", contentType);
this.content_type = contentType;
}
/**
* Gets download count.
*
* @return the download count
*/
public long getDownloadCount() {
return download_count;
}
/**
* Gets label.
*
* @return the label
*/
public String getLabel() {
return label;
}
/**
* Sets label.
*
* @param label
* the label
* @throws IOException
* the io exception
*/
public void setLabel(String label) throws IOException {
edit("label", label);
this.label = label;
}
/**
* Gets name.
*
* @return the name
*/
public String getName() {
return name;
}
/**
* Gets owner.
*
* @return the owner
*/
public GHRepository getOwner() {
return owner;
}
/**
* Gets root.
*
* @return the root
*/
public GitHub getRoot() {
return root;
}
/**
* Gets size.
*
* @return the size
*/
public long getSize() {
return size;
}
/**
* Gets state.
*
* @return the state
*/
public String getState() {
return state;
}
@@ -69,19 +125,29 @@ public class GHAsset extends GHObject {
return null;
}
/**
* Gets browser download url.
*
* @return the browser download url
*/
public String getBrowserDownloadUrl() {
return browser_download_url;
}
private void edit(String key, Object value) throws IOException {
new Requester(root)._with(key, value).method("PATCH").to(getApiRoute());
new Requester(root).with(key, value).method("PATCH").to(getApiRoute());
}
/**
* Delete.
*
* @throws IOException
* the io exception
*/
public void delete() throws IOException {
new Requester(root).method("DELETE").to(getApiRoute());
}
private String getApiRoute() {
return "/repos/" + owner.getOwnerName() + "/" + owner.getName() + "/releases/assets/" + id;
}
@@ -92,6 +158,15 @@ public class GHAsset extends GHObject {
return this;
}
/**
* Wrap gh asset [ ].
*
* @param assets
* the assets
* @param release
* the release
* @return the gh asset [ ]
*/
public static GHAsset[] wrap(GHAsset[] assets, GHRelease release) {
for (GHAsset aTo : assets) {
aTo.wrap(release);

View File

@@ -10,7 +10,7 @@ import java.util.List;
* Generated OAuth token
*
* @author janinko
* @see GitHub#createToken(Collection, String, String)
* @see GitHub#createToken(Collection, String, String) GitHub#createToken(Collection, String, String)
* @see <a href="http://developer.github.com/v3/oauth/#create-a-new-authorization">API documentation</a>
*/
public class GHAuthorization extends GHObject {
@@ -42,39 +42,78 @@ public class GHAuthorization extends GHObject {
private String note;
private String note_url;
private String fingerprint;
//TODO add some user class for https://developer.github.com/v3/oauth_authorizations/#check-an-authorization ?
//private GHUser user;
// TODO add some user class for https://developer.github.com/v3/oauth_authorizations/#check-an-authorization ?
// private GHUser user;
/**
* Gets root.
*
* @return the root
*/
public GitHub getRoot() {
return root;
}
/**
* Gets scopes.
*
* @return the scopes
*/
public List<String> getScopes() {
return scopes;
}
/**
* Gets token.
*
* @return the token
*/
public String getToken() {
return token;
}
/**
* Gets token last eight.
*
* @return the token last eight
*/
public String getTokenLastEight() {
return token_last_eight;
}
/**
* Gets hashed token.
*
* @return the hashed token
*/
public String getHashedToken() {
return hashed_token;
}
/**
* Gets app url.
*
* @return the app url
*/
public URL getAppUrl() {
return GitHub.parseURL(app.url);
}
/**
* Gets app name.
*
* @return the app name
*/
public String getAppName() {
return app.name;
}
@SuppressFBWarnings(value = "NM_CONFUSING",
justification = "It's a part of the library API, cannot be changed")
/**
* Gets api url.
*
* @return the api url
*/
@SuppressFBWarnings(value = "NM_CONFUSING", justification = "It's a part of the library API, cannot be changed")
public URL getApiURL() {
return GitHub.parseURL(url);
}
@@ -87,25 +126,40 @@ public class GHAuthorization extends GHObject {
return null;
}
/**
* Gets note.
*
* @return the note
*/
public String getNote() {
return note;
}
/**
* Gets note url.
*
* @return the note url
*/
public URL getNoteUrl() {
return GitHub.parseURL(note_url);
}
/**
* Gets fingerprint.
*
* @return the fingerprint
*/
public String getFingerprint() {
return fingerprint;
}
/*package*/ GHAuthorization wrap(GitHub root) {
GHAuthorization wrap(GitHub root) {
this.root = root;
return this;
}
@SuppressFBWarnings(value = {"UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD"},
justification = "JSON API")
@SuppressFBWarnings(value = { "UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD" },
justification = "JSON API")
private static class App {
private String url;
private String name;

View File

@@ -8,10 +8,12 @@ import java.io.UnsupportedEncodingException;
import java.net.URL;
/**
* The type GHBlob.
*
* @author Kanstantsin Shautsou
* @author Kohsuke Kawaguchi
* @see GHTreeEntry#asBlob()
* @see GHRepository#getBlob(String)
* @see GHTreeEntry#asBlob() GHTreeEntry#asBlob()
* @see GHRepository#getBlob(String) GHRepository#getBlob(String)
* @see <a href="https://developer.github.com/v3/git/blobs/#get-a-blob">Get a blob</a>
*/
public class GHBlob {
@@ -19,46 +21,64 @@ public class GHBlob {
private long size;
/**
* API URL of this blob.
* Gets url.
*
* @return API URL of this blob.
*/
public URL getUrl() {
return GitHub.parseURL(url);
}
/**
* Gets sha.
*
* @return the sha
*/
public String getSha() {
return sha;
}
/**
* Number of bytes in this blob.
* Gets size.
*
* @return Number of bytes in this blob.
*/
public long getSize() {
return size;
}
/**
* Gets encoding.
*
* @return the encoding
*/
public String getEncoding() {
return encoding;
}
/**
* Encoded content. You probably want {@link #read()}
* Gets content.
*
* @return Encoded content. You probably want {@link #read()}
*/
public String getContent() {
return content;
}
/**
* Retrieves the actual bytes of the blob.
* Read input stream.
*
* @return the actual bytes of the blob.
*/
public InputStream read() {
if (encoding.equals("base64")) {
try {
return new Base64InputStream(new ByteArrayInputStream(content.getBytes("US-ASCII")), false);
} catch (UnsupportedEncodingException e) {
throw new AssertionError(e); // US-ASCII is mandatory
throw new AssertionError(e); // US-ASCII is mandatory
}
}
throw new UnsupportedOperationException("Unrecognized encoding: "+encoding);
throw new UnsupportedOperationException("Unrecognized encoding: " + encoding);
}
}

View File

@@ -5,8 +5,7 @@ import org.apache.commons.codec.binary.Base64;
import java.io.IOException;
/**
* Builder pattern for creating a new blob.
* Based on https://developer.github.com/v3/git/blobs/#create-a-blob
* Builder pattern for creating a new blob. Based on https://developer.github.com/v3/git/blobs/#create-a-blob
*/
public class GHBlobBuilder {
private final GHRepository repo;
@@ -19,6 +18,10 @@ public class GHBlobBuilder {
/**
* Configures a blob with the specified text {@code content}.
*
* @param content
* string text of the blob
* @return a GHBlobBuilder
*/
public GHBlobBuilder textContent(String content) {
req.with("content", content);
@@ -28,6 +31,10 @@ public class GHBlobBuilder {
/**
* Configures a blob with the specified binary {@code content}.
*
* @param content
* byte array of the blob
* @return a GHBlobBuilder
*/
public GHBlobBuilder binaryContent(byte[] content) {
String base64Content = Base64.encodeBase64String(content);
@@ -42,6 +49,10 @@ public class GHBlobBuilder {
/**
* Creates a blob based on the parameters specified thus far.
*
* @return a GHBlob
* @throws IOException
* if the blob cannot be created.
*/
public GHBlob create() throws IOException {
return req.method("POST").to(getApiTail(), GHBlob.class);

View File

@@ -1,11 +1,13 @@
package org.kohsuke.github;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.io.IOException;
import java.net.URL;
import java.util.Collection;
import java.util.Objects;
import static org.kohsuke.github.Previews.*;
@@ -14,8 +16,10 @@ import static org.kohsuke.github.Previews.*;
*
* @author Yusuke Kokubo
*/
@SuppressFBWarnings(value = {"UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD",
"NP_UNWRITTEN_FIELD", "URF_UNREAD_FIELD"}, justification = "JSON API")
@SuppressFBWarnings(
value = { "UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD", "NP_UNWRITTEN_FIELD",
"URF_UNREAD_FIELD" },
justification = "JSON API")
public class GHBranch {
private GitHub root;
private GHRepository owner;
@@ -26,7 +30,15 @@ public class GHBranch {
private boolean protection;
private String protection_url;
@JsonCreator
GHBranch(@JsonProperty(value = "name", required = true) String name) throws Exception {
Objects.requireNonNull(name);
this.name = name;
}
/**
* The type Commit.
*/
public static class Commit {
String sha;
@@ -34,44 +46,70 @@ public class GHBranch {
String url;
}
/**
* Gets root.
*
* @return the root
*/
public GitHub getRoot() {
return root;
}
/**
* Repository that this branch is in.
* Gets owner.
*
* @return the repository that this branch is in.
*/
public GHRepository getOwner() {
return owner;
}
/**
* Gets name.
*
* @return the name
*/
public String getName() {
return name;
}
/**
* Returns true if the push to this branch is restricted via branch protection.
* Is protected boolean.
*
* @return true if the push to this branch is restricted via branch protection.
*/
@Preview @Deprecated
@Preview
@Deprecated
public boolean isProtected() {
return protection;
}
/**
* Returns API URL that deals with the protection of this branch.
* Gets protection url.
*
* @return API URL that deals with the protection of this branch.
*/
@Preview @Deprecated
@Preview
@Deprecated
public URL getProtectionUrl() {
return GitHub.parseURL(protection_url);
}
@Preview @Deprecated
/**
* Gets protection.
*
* @return the protection
* @throws IOException
* the io exception
*/
public GHBranchProtection getProtection() throws IOException {
return root.retrieve().withPreview(LOKI).to(protection_url, GHBranchProtection.class);
return root.retrieve().to(protection_url, GHBranchProtection.class).wrap(this);
}
/**
* The commit that this branch currently points to.
* Gets sha 1.
*
* @return The SHA1 of the commit that this branch currently points to.
*/
public String getSHA1() {
return commit.sha;
@@ -79,41 +117,54 @@ public class GHBranch {
/**
* Disables branch protection and allows anyone with push access to push changes.
*
* @throws IOException
* if disabling protection fails
*/
@Preview @Deprecated
public void disableProtection() throws IOException {
new Requester(root).method("DELETE").withPreview(LOKI).to(protection_url);
new Requester(root).method("DELETE").to(protection_url);
}
/**
* Enables branch protection to control what commit statuses are required to push.
*
* @see GHCommitStatus#getContext()
* @return GHBranchProtectionBuilder for enabling protection
* @see GHCommitStatus#getContext() GHCommitStatus#getContext()
*/
@Preview @Deprecated
@Preview
@Deprecated
public GHBranchProtectionBuilder enableProtection() {
return new GHBranchProtectionBuilder(this);
}
/**
* Enable protection.
*
* @param level
* the level
* @param contexts
* the contexts
* @throws IOException
* the io exception
*/
// backward compatibility with previous signature
@Deprecated
public void enableProtection(EnforcementLevel level, Collection<String> contexts) throws IOException {
switch (level) {
case OFF:
disableProtection();
break;
case NON_ADMINS:
case EVERYONE:
enableProtection()
.addRequiredChecks(contexts)
.includeAdmins(level==EnforcementLevel.EVERYONE)
.enable();
break;
case OFF :
disableProtection();
break;
case NON_ADMINS :
case EVERYONE :
enableProtection().addRequiredChecks(contexts)
.includeAdmins(level == EnforcementLevel.EVERYONE)
.enable();
break;
}
}
String getApiRoute() {
return owner.getApiTailUrl("/branches/"+name);
return owner.getApiTailUrl("/branches/" + name);
}
@Override
@@ -122,7 +173,7 @@ public class GHBranch {
return "Branch:" + name + " in " + url;
}
/*package*/ GHBranch wrap(GHRepository repo) {
GHBranch wrap(GHRepository repo) {
this.owner = repo;
this.root = repo.root;
return this;

View File

@@ -3,149 +3,348 @@ package org.kohsuke.github;
import com.fasterxml.jackson.annotation.JsonProperty;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.io.IOException;
import java.util.Collection;
@SuppressFBWarnings(value = { "UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD", "NP_UNWRITTEN_FIELD",
"URF_UNREAD_FIELD" }, justification = "JSON API")
import static org.kohsuke.github.Previews.ZZZAX;
/**
* The type GHBranchProtection.
*/
@SuppressFBWarnings(
value = { "UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD", "NP_UNWRITTEN_FIELD",
"URF_UNREAD_FIELD" },
justification = "JSON API")
public class GHBranchProtection {
@JsonProperty("enforce_admins")
private EnforceAdmins enforceAdmins;
private static final String REQUIRE_SIGNATURES_URI = "/required_signatures";
@JsonProperty("required_pull_request_reviews")
private RequiredReviews requiredReviews;
@JsonProperty
private EnforceAdmins enforceAdmins;
@JsonProperty("required_status_checks")
private RequiredStatusChecks requiredStatusChecks;
private GitHub root;
@JsonProperty
private Restrictions restrictions;
@JsonProperty("required_pull_request_reviews")
private RequiredReviews requiredReviews;
@JsonProperty
private String url;
public EnforceAdmins getEnforceAdmins() {
@JsonProperty
private RequiredStatusChecks requiredStatusChecks;
@JsonProperty
private Restrictions restrictions;
@JsonProperty
private String url;
/**
* Enabled signed commits.
*
* @throws IOException
* the io exception
*/
@Preview
@Deprecated
public void enabledSignedCommits() throws IOException {
requester().method("POST").to(url + REQUIRE_SIGNATURES_URI, RequiredSignatures.class);
}
/**
* Disable signed commits.
*
* @throws IOException
* the io exception
*/
@Preview
@Deprecated
public void disableSignedCommits() throws IOException {
requester().method("DELETE").to(url + REQUIRE_SIGNATURES_URI);
}
/**
* Gets enforce admins.
*
* @return the enforce admins
*/
public EnforceAdmins getEnforceAdmins() {
return enforceAdmins;
}
/**
* Gets required reviews.
*
* @return the required reviews
*/
public RequiredReviews getRequiredReviews() {
return requiredReviews;
}
/**
* Gets required signatures.
*
* @return the required signatures
* @throws IOException
* the io exception
*/
@Preview
@Deprecated
public boolean getRequiredSignatures() throws IOException {
return requester().method("GET").to(url + REQUIRE_SIGNATURES_URI, RequiredSignatures.class).enabled;
}
/**
* Gets required status checks.
*
* @return the required status checks
*/
public RequiredStatusChecks getRequiredStatusChecks() {
return requiredStatusChecks;
}
/**
* Gets restrictions.
*
* @return the restrictions
*/
public Restrictions getRestrictions() {
return restrictions;
}
/**
* Gets url.
*
* @return the url
*/
public String getUrl() {
return url;
}
GHBranchProtection wrap(GHBranch branch) {
this.root = branch.getRoot();
return this;
}
private Requester requester() {
return new Requester(root).withPreview(ZZZAX);
}
/**
* The type EnforceAdmins.
*/
public static class EnforceAdmins {
@JsonProperty
private boolean enabled;
@JsonProperty
private boolean enabled;
@JsonProperty
private String url;
@JsonProperty
private String url;
/**
* Gets url.
*
* @return the url
*/
public String getUrl() {
return url;
}
/**
* Is enabled boolean.
*
* @return the boolean
*/
public boolean isEnabled() {
return enabled;
}
}
}
public static class RequiredReviews {
@JsonProperty("dismissal_restrictions")
private Restrictions dismissalRestriction;
/**
* The type RequiredReviews.
*/
public static class RequiredReviews {
@JsonProperty("dismissal_restrictions")
private Restrictions dismissalRestriction;
@JsonProperty("dismiss_stale_reviews")
private boolean dismissStaleReviews;
private boolean dismissStaleReviews;
@JsonProperty("require_code_owner_reviews")
private boolean requireCodeOwnerReviews;
private boolean requireCodeOwnerReviews;
@JsonProperty
private String url;
@JsonProperty("required_approving_review_count")
private int requiredReviewers;
@JsonProperty
private String url;
/**
* Gets dismissal restrictions.
*
* @return the dismissal restrictions
*/
public Restrictions getDismissalRestrictions() {
return dismissalRestriction;
}
/**
* Gets url.
*
* @return the url
*/
public String getUrl() {
return url;
}
/**
* Is dismiss stale reviews boolean.
*
* @return the boolean
*/
public boolean isDismissStaleReviews() {
return dismissStaleReviews;
}
/**
* Is require code owner reviews boolean.
*
* @return the boolean
*/
public boolean isRequireCodeOwnerReviews() {
return requireCodeOwnerReviews;
}
}
public static class RequiredStatusChecks {
@JsonProperty
private Collection<String> contexts;
/**
* Gets required reviewers.
*
* @return the required reviewers
*/
public int getRequiredReviewers() {
return requiredReviewers;
}
}
@JsonProperty
private boolean strict;
private static class RequiredSignatures {
@JsonProperty
private boolean enabled;
@JsonProperty
private String url;
@JsonProperty
private String url;
/**
* Gets url.
*
* @return the url
*/
public String getUrl() {
return url;
}
/**
* Is enabled boolean.
*
* @return the boolean
*/
public boolean isEnabled() {
return enabled;
}
}
/**
* The type RequiredStatusChecks.
*/
public static class RequiredStatusChecks {
@JsonProperty
private Collection<String> contexts;
@JsonProperty
private boolean strict;
@JsonProperty
private String url;
/**
* Gets contexts.
*
* @return the contexts
*/
public Collection<String> getContexts() {
return contexts;
}
/**
* Gets url.
*
* @return the url
*/
public String getUrl() {
return url;
}
/**
* Is requires branch up to date boolean.
*
* @return the boolean
*/
public boolean isRequiresBranchUpToDate() {
return strict;
}
}
}
public static class Restrictions {
@JsonProperty
private Collection<GHTeam> teams;
/**
* The type Restrictions.
*/
public static class Restrictions {
@JsonProperty
private Collection<GHTeam> teams;
@JsonProperty("teams_url")
private String teamsUrl;
private String teamsUrl;
@JsonProperty
private String url;
@JsonProperty
private String url;
@JsonProperty
private Collection<GHUser> users;
@JsonProperty
private Collection<GHUser> users;
@JsonProperty("users_url")
private String usersUrl;
private String usersUrl;
/**
* Gets teams.
*
* @return the teams
*/
public Collection<GHTeam> getTeams() {
return teams;
}
/**
* Gets teams url.
*
* @return the teams url
*/
public String getTeamsUrl() {
return teamsUrl;
}
/**
* Gets url.
*
* @return the url
*/
public String getUrl() {
return url;
}
/**
* Gets users.
*
* @return the users
*/
public Collection<GHUser> getUsers() {
return users;
}
/**
* Gets users url.
*
* @return the users url
*/
public String getUsersUrl() {
return usersUrl;
}
}
}
}

View File

@@ -17,10 +17,12 @@ import static org.kohsuke.github.Previews.*;
/**
* Builder to configure the branch protection settings.
*
* @see GHBranch#enableProtection()
* @see GHBranch#enableProtection() GHBranch#enableProtection()
*/
@SuppressFBWarnings(value = { "UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD", "NP_UNWRITTEN_FIELD",
"URF_UNREAD_FIELD" }, justification = "JSON API")
@SuppressFBWarnings(
value = { "UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD", "NP_UNWRITTEN_FIELD",
"URF_UNREAD_FIELD" },
justification = "JSON API")
public class GHBranchProtectionBuilder {
private final GHBranch branch;
@@ -33,67 +35,185 @@ public class GHBranchProtectionBuilder {
this.branch = branch;
}
/**
* Add required checks gh branch protection builder.
*
* @param checks
* the checks
* @return the gh branch protection builder
*/
public GHBranchProtectionBuilder addRequiredChecks(Collection<String> checks) {
getStatusChecks().contexts.addAll(checks);
return this;
}
/**
* Add required checks gh branch protection builder.
*
* @param checks
* the checks
* @return the gh branch protection builder
*/
public GHBranchProtectionBuilder addRequiredChecks(String... checks) {
addRequiredChecks(Arrays.asList(checks));
return this;
}
/**
* Dismiss stale reviews gh branch protection builder.
*
* @return the gh branch protection builder
*/
public GHBranchProtectionBuilder dismissStaleReviews() {
getPrReviews().put("dismiss_stale_reviews", true);
return dismissStaleReviews(true);
}
/**
* Dismiss stale reviews gh branch protection builder.
*
* @param v
* the v
* @return the gh branch protection builder
*/
public GHBranchProtectionBuilder dismissStaleReviews(boolean v) {
getPrReviews().put("dismiss_stale_reviews", v);
return this;
}
/**
* Enable gh branch protection.
*
* @return the gh branch protection
* @throws IOException
* the io exception
*/
public GHBranchProtection enable() throws IOException {
return requester().method("PUT")
.withNullable("required_status_checks", statusChecks)
.withNullable("required_pull_request_reviews", prReviews)
.withNullable("restrictions", restrictions)
.withNullable("enforce_admins", enforceAdmins)
.to(branch.getProtectionUrl().toString(), GHBranchProtection.class);
.to(branch.getProtectionUrl().toString(), GHBranchProtection.class)
.wrap(branch);
}
/**
* Include admins gh branch protection builder.
*
* @return the gh branch protection builder
*/
public GHBranchProtectionBuilder includeAdmins() {
return includeAdmins(true);
}
/**
* Include admins gh branch protection builder.
*
* @param v
* the v
* @return the gh branch protection builder
*/
public GHBranchProtectionBuilder includeAdmins(boolean v) {
enforceAdmins = v;
return this;
}
/**
* Required reviewers gh branch protection builder.
*
* @param v
* the v
* @return the gh branch protection builder
*/
public GHBranchProtectionBuilder requiredReviewers(int v) {
getPrReviews().put("required_approving_review_count", v);
return this;
}
/**
* Require branch is up to date gh branch protection builder.
*
* @return the gh branch protection builder
*/
public GHBranchProtectionBuilder requireBranchIsUpToDate() {
return requireBranchIsUpToDate(true);
}
/**
* Require branch is up to date gh branch protection builder.
*
* @param v
* the v
* @return the gh branch protection builder
*/
public GHBranchProtectionBuilder requireBranchIsUpToDate(boolean v) {
getStatusChecks().strict = v;
return this;
}
/**
* Require code own reviews gh branch protection builder.
*
* @return the gh branch protection builder
*/
public GHBranchProtectionBuilder requireCodeOwnReviews() {
return requireCodeOwnReviews(true);
}
/**
* Require code own reviews gh branch protection builder.
*
* @param v
* the v
* @return the gh branch protection builder
*/
public GHBranchProtectionBuilder requireCodeOwnReviews(boolean v) {
getPrReviews().put("require_code_owner_reviews", v);
return this;
}
/**
* Require reviews gh branch protection builder.
*
* @return the gh branch protection builder
*/
public GHBranchProtectionBuilder requireReviews() {
getPrReviews();
return this;
}
/**
* Restrict review dismissals gh branch protection builder.
*
* @return the gh branch protection builder
*/
public GHBranchProtectionBuilder restrictReviewDismissals() {
getPrReviews();
if (!prReviews.containsKey("dismissal_restrictions")) {
prReviews.put("dismissal_restrictions", new Restrictions());
}
return this;
}
/**
* Restrict push access gh branch protection builder.
*
* @return the gh branch protection builder
*/
public GHBranchProtectionBuilder restrictPushAccess() {
getRestrictions();
return this;
}
/**
* Team push access gh branch protection builder.
*
* @param teams
* the teams
* @return the gh branch protection builder
*/
public GHBranchProtectionBuilder teamPushAccess(Collection<GHTeam> teams) {
for (GHTeam team : teams) {
teamPushAccess(team);
@@ -101,6 +221,13 @@ public class GHBranchProtectionBuilder {
return this;
}
/**
* Team push access gh branch protection builder.
*
* @param teams
* the teams
* @return the gh branch protection builder
*/
public GHBranchProtectionBuilder teamPushAccess(GHTeam... teams) {
for (GHTeam team : teams) {
getRestrictions().teams.add(team.getSlug());
@@ -108,6 +235,13 @@ public class GHBranchProtectionBuilder {
return this;
}
/**
* Team review dismissals gh branch protection builder.
*
* @param teams
* the teams
* @return the gh branch protection builder
*/
public GHBranchProtectionBuilder teamReviewDismissals(Collection<GHTeam> teams) {
for (GHTeam team : teams) {
teamReviewDismissals(team);
@@ -115,6 +249,13 @@ public class GHBranchProtectionBuilder {
return this;
}
/**
* Team review dismissals gh branch protection builder.
*
* @param teams
* the teams
* @return the gh branch protection builder
*/
public GHBranchProtectionBuilder teamReviewDismissals(GHTeam... teams) {
for (GHTeam team : teams) {
addReviewRestriction(team.getSlug(), true);
@@ -122,13 +263,27 @@ public class GHBranchProtectionBuilder {
return this;
}
/**
* User push access gh branch protection builder.
*
* @param users
* the users
* @return the gh branch protection builder
*/
public GHBranchProtectionBuilder userPushAccess(Collection<GHUser> users) {
for (GHUser user : users) {
userPushAccess(user);
}
return this;
}
/**
* User push access gh branch protection builder.
*
* @param users
* the users
* @return the gh branch protection builder
*/
public GHBranchProtectionBuilder userPushAccess(GHUser... users) {
for (GHUser user : users) {
getRestrictions().users.add(user.getLogin());
@@ -136,6 +291,13 @@ public class GHBranchProtectionBuilder {
return this;
}
/**
* User review dismissals gh branch protection builder.
*
* @param users
* the users
* @return the gh branch protection builder
*/
public GHBranchProtectionBuilder userReviewDismissals(Collection<GHUser> users) {
for (GHUser team : users) {
userReviewDismissals(team);
@@ -143,6 +305,13 @@ public class GHBranchProtectionBuilder {
return this;
}
/**
* User review dismissals gh branch protection builder.
*
* @param users
* the users
* @return the gh branch protection builder
*/
public GHBranchProtectionBuilder userReviewDismissals(GHUser... users) {
for (GHUser user : users) {
addReviewRestriction(user.getLogin(), false);
@@ -151,14 +320,9 @@ public class GHBranchProtectionBuilder {
}
private void addReviewRestriction(String restriction, boolean isTeam) {
getPrReviews();
if (!prReviews.containsKey("dismissal_restrictions")) {
prReviews.put("dismissal_restrictions", new Restrictions());
}
restrictReviewDismissals();
Restrictions restrictions = (Restrictions) prReviews.get("dismissal_restrictions");
if (isTeam) {
restrictions.teams.add(restriction);
} else {
@@ -188,7 +352,7 @@ public class GHBranchProtectionBuilder {
}
private Requester requester() {
return new Requester(branch.getRoot()).withPreview(LOKI);
return new Requester(branch.getRoot()).withPreview(LUKE_CAGE);
}
private static class Restrictions {

View File

@@ -0,0 +1,37 @@
package org.kohsuke.github;
/**
* How is an user associated with a repository?
*
* @author Kohsuke Kawaguchi
*/
public enum GHCommentAuthorAssociation {
/**
* Author has been invited to collaborate on the repository.
*/
COLLABORATOR,
/**
* Author has previously committed to the repository.
*/
CONTRIBUTOR,
/**
* Author has not previously committed to GitHub.
*/
FIRST_TIMER,
/**
* Author has not previously committed to the repository.
*/
FIRST_TIME_CONTRIBUTOR,
/**
* Author is a member of the organization that owns the repository.
*/
MEMBER,
/**
* Author has no association with the repository.
*/
NONE,
/**
* Author is the owner of the repository.
*/
OWNER
}

View File

@@ -15,27 +15,28 @@ import java.util.List;
* A commit in a repository.
*
* @author Kohsuke Kawaguchi
* @see GHRepository#getCommit(String)
* @see GHCommitComment#getCommit()
* @see GHRepository#getCommit(String) GHRepository#getCommit(String)
* @see GHCommitComment#getCommit() GHCommitComment#getCommit()
*/
@SuppressFBWarnings(value = {"NP_UNWRITTEN_FIELD", "UWF_UNWRITTEN_FIELD"},
justification = "JSON API")
@SuppressFBWarnings(value = { "NP_UNWRITTEN_FIELD", "UWF_UNWRITTEN_FIELD" }, justification = "JSON API")
public class GHCommit {
private GHRepository owner;
private ShortInfo commit;
/**
* Short summary of this commit.
*/
@SuppressFBWarnings(value = {"UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD",
"NP_UNWRITTEN_FIELD", "UWF_UNWRITTEN_FIELD"}, justification = "JSON API")
@SuppressFBWarnings(
value = { "UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD", "NP_UNWRITTEN_FIELD",
"UWF_UNWRITTEN_FIELD" },
justification = "JSON API")
public static class ShortInfo {
private GHAuthor author;
private GHAuthor committer;
private String message;
private int comment_count;
static class Tree {
@@ -44,88 +45,129 @@ public class GHCommit {
private Tree tree;
/**
* Gets author.
*
* @return the author
*/
@WithBridgeMethods(value = GHAuthor.class, castRequired = true)
public GitUser getAuthor() {
return author;
}
/**
* Gets authored date.
*
* @return the authored date
*/
public Date getAuthoredDate() {
return GitHub.parseDate(author.date);
}
/**
* Gets committer.
*
* @return the committer
*/
@WithBridgeMethods(value = GHAuthor.class, castRequired = true)
public GitUser getCommitter() {
return committer;
}
/**
* Gets commit date.
*
* @return the commit date
*/
public Date getCommitDate() {
return GitHub.parseDate(committer.date);
}
/**
* Commit message.
* Gets message.
*
* @return Commit message.
*/
public String getMessage() {
return message;
}
/**
* Gets comment count.
*
* @return the comment count
*/
public int getCommentCount() {
return comment_count;
}
}
/**
* The type GHAuthor.
*
* @deprecated Use {@link GitUser} instead.
*/
public static class GHAuthor extends GitUser {
private String date;
}
/**
* The type Stats.
*/
public static class Stats {
int total,additions,deletions;
int total, additions, deletions;
}
/**
* A file that was modified.
*/
@SuppressFBWarnings(value = "UWF_UNWRITTEN_FIELD",
justification = "It's being initilized by JSON deserialization")
@SuppressFBWarnings(value = "UWF_UNWRITTEN_FIELD", justification = "It's being initilized by JSON deserialization")
public static class File {
String status;
int changes,additions,deletions;
int changes, additions, deletions;
String raw_url, blob_url, sha, patch;
String filename, previous_filename;
/**
* Number of lines added + removed.
* Gets lines changed.
*
* @return Number of lines added + removed.
*/
public int getLinesChanged() {
return changes;
}
/**
* Number of lines added.
* Gets lines added.
*
* @return Number of lines added.
*/
public int getLinesAdded() {
return additions;
}
/**
* Number of lines removed.
* Gets lines deleted.
*
* @return Number of lines removed.
*/
public int getLinesDeleted() {
return deletions;
}
/**
* "modified", "added", or "removed"
* Gets status.
*
* @return "modified", "added", or "removed"
*/
public String getStatus() {
return status;
}
/**
* Full path in the repository.
* Gets file name.
*
* @return Full path in the repository.
*/
@SuppressFBWarnings(value = "NM_CONFUSING",
justification = "It's a part of the library's API and cannot be renamed")
@@ -134,81 +176,108 @@ public class GHCommit {
}
/**
* Previous path, in case file has moved.
* Gets previous filename.
*
* @return Previous path, in case file has moved.
*/
public String getPreviousFilename() {
return previous_filename;
}
/**
* The actual change.
* Gets patch.
*
* @return The actual change.
*/
public String getPatch() {
return patch;
}
/**
* URL like 'https://raw.github.com/jenkinsci/jenkins/4eb17c197dfdcf8ef7ff87eb160f24f6a20b7f0e/core/pom.xml'
* that resolves to the actual content of the file.
* Gets raw url.
*
* @return URL like
* 'https://raw.github.com/jenkinsci/jenkins/4eb17c197dfdcf8ef7ff87eb160f24f6a20b7f0e/core/pom.xml' that
* resolves to the actual content of the file.
*/
public URL getRawUrl() {
return GitHub.parseURL(raw_url);
}
/**
* URL like 'https://github.com/jenkinsci/jenkins/blob/1182e2ebb1734d0653142bd422ad33c21437f7cf/core/pom.xml'
* that resolves to the HTML page that describes this file.
* Gets blob url.
*
* @return URL like
* 'https://github.com/jenkinsci/jenkins/blob/1182e2ebb1734d0653142bd422ad33c21437f7cf/core/pom.xml'
* that resolves to the HTML page that describes this file.
*/
public URL getBlobUrl() {
return GitHub.parseURL(blob_url);
}
/**
* [0-9a-f]{40} SHA1 checksum.
* Gets sha.
*
* @return [0 -9a-f]{40} SHA1 checksum.
*/
public String getSha() {
return sha;
}
}
/**
* The type Parent.
*/
public static class Parent {
@SuppressFBWarnings(value = "UUF_UNUSED_FIELD", justification = "We don't provide it in API now")
String url;
String url;
String sha;
}
static class User {
// TODO: what if someone who doesn't have an account on GitHub makes a commit?
@SuppressFBWarnings(value = "UUF_UNUSED_FIELD", justification = "We don't provide it in API now")
String url,avatar_url,gravatar_id;
String url, avatar_url, gravatar_id;
@SuppressFBWarnings(value = "UUF_UNUSED_FIELD", justification = "We don't provide it in API now")
int id;
String login;
}
String url,html_url,sha;
String url, html_url, sha;
List<File> files;
Stats stats;
List<Parent> parents;
User author,committer;
User author, committer;
/**
* Gets commit short info.
*
* @return the commit short info
* @throws IOException
* the io exception
*/
public ShortInfo getCommitShortInfo() throws IOException {
if (commit==null)
if (commit == null)
populate();
return commit;
}
/**
* The repository that contains the commit.
* Gets owner.
*
* @return the repository that contains the commit.
*/
public GHRepository getOwner() {
return owner;
}
/**
* Number of lines added + removed.
* Gets lines changed.
*
* @return the number of lines added + removed.
* @throws IOException
* if the field was not populated and refresh fails
*/
public int getLinesChanged() throws IOException {
populate();
@@ -216,7 +285,11 @@ public class GHCommit {
}
/**
* Number of lines added.
* Gets lines added.
*
* @return Number of lines added.
* @throws IOException
* if the field was not populated and refresh fails
*/
public int getLinesAdded() throws IOException {
populate();
@@ -224,7 +297,11 @@ public class GHCommit {
}
/**
* Number of lines removed.
* Gets lines deleted.
*
* @return Number of lines removed.
* @throws IOException
* if the field was not populated and refresh fails
*/
public int getLinesDeleted() throws IOException {
populate();
@@ -232,21 +309,30 @@ public class GHCommit {
}
/**
* Use this method to walk the tree
* Use this method to walk the tree.
*
* @return a GHTree to walk
* @throws IOException
* on error
*/
public GHTree getTree() throws IOException {
return owner.getTree(getCommitShortInfo().tree.sha);
}
/**
* URL of this commit like "https://github.com/kohsuke/sandbox-ant/commit/8ae38db0ea5837313ab5f39d43a6f73de3bd9000"
* Gets html url.
*
* @return URL of this commit like
* "https://github.com/kohsuke/sandbox-ant/commit/8ae38db0ea5837313ab5f39d43a6f73de3bd9000"
*/
public URL getHtmlUrl() {
return GitHub.parseURL(html_url);
}
/**
* [0-9a-f]{40} SHA1 checksum.
* Gets sha 1.
*
* @return [0 -9a-f]{40} SHA1 checksum.
*/
public String getSHA1() {
return sha;
@@ -255,19 +341,23 @@ public class GHCommit {
/**
* List of files changed/added/removed in this commit.
*
* @return
* Can be empty but never null.
* @return Can be empty but never null.
* @throws IOException
* on error
*/
public List<File> getFiles() throws IOException {
populate();
return files!=null ? Collections.unmodifiableList(files) : Collections.<File>emptyList();
return files != null ? Collections.unmodifiableList(files) : Collections.<File>emptyList();
}
/**
* Returns the SHA1 of parent commit objects.
* Gets parent sha 1 s.
*
* @return SHA1 of parent commit objects.
*/
public List<String> getParentSHA1s() {
if (parents==null) return Collections.emptyList();
if (parents == null)
return Collections.emptyList();
return new AbstractList<String>() {
@Override
public String get(int index) {
@@ -283,6 +373,10 @@ public class GHCommit {
/**
* Resolves the parent commit objects and return them.
*
* @return parent commit objects
* @throws IOException
* on error
*/
public List<GHCommit> getParents() throws IOException {
List<GHCommit> r = new ArrayList<GHCommit>();
@@ -291,19 +385,35 @@ public class GHCommit {
return r;
}
/**
* Gets author.
*
* @return the author
* @throws IOException
* the io exception
*/
public GHUser getAuthor() throws IOException {
return resolveUser(author);
}
/**
* Gets the date the change was authored on.
*
* @return the date the change was authored on.
* @throws IOException if the information was not already fetched and an attempt at fetching the information failed.
* @throws IOException
* if the information was not already fetched and an attempt at fetching the information failed.
*/
public Date getAuthoredDate() throws IOException {
return getCommitShortInfo().getAuthoredDate();
}
/**
* Gets committer.
*
* @return the committer
* @throws IOException
* the io exception
*/
public GHUser getCommitter() throws IOException {
return resolveUser(committer);
}
@@ -312,62 +422,89 @@ public class GHCommit {
* Gets the date the change was committed on.
*
* @return the date the change was committed on.
* @throws IOException if the information was not already fetched and an attempt at fetching the information failed.
* @throws IOException
* if the information was not already fetched and an attempt at fetching the information failed.
*/
public Date getCommitDate() throws IOException {
return getCommitShortInfo().getCommitDate();
}
private GHUser resolveUser(User author) throws IOException {
if (author==null || author.login==null) return null;
if (author == null || author.login == null)
return null;
return owner.root.getUser(author.login);
}
/**
* Lists up all the commit comments in this repository.
* List comments paged iterable.
*
* @return {@link PagedIterable} with all the commit comments in this repository.
*/
public PagedIterable<GHCommitComment> listComments() {
return new PagedIterable<GHCommitComment>() {
public PagedIterator<GHCommitComment> _iterator(int pageSize) {
return new PagedIterator<GHCommitComment>(owner.root.retrieve().asIterator(String.format("/repos/%s/%s/commits/%s/comments", owner.getOwnerName(), owner.getName(), sha), GHCommitComment[].class, pageSize)) {
@Override
protected void wrapUp(GHCommitComment[] page) {
for (GHCommitComment c : page)
c.wrap(owner);
}
};
}
};
return owner.root.retrieve()
.asPagedIterable(
String.format("/repos/%s/%s/commits/%s/comments", owner.getOwnerName(), owner.getName(), sha),
GHCommitComment[].class,
item -> item.wrap(owner));
}
/**
* Creates a commit comment.
*
* <p>
* I'm not sure how path/line/position parameters interact with each other.
*
* @param body
* body of the comment
* @param path
* path of file being commented on
* @param line
* target line for comment
* @param position
* position on line
* @return created GHCommitComment
* @throws IOException
* if comment is not created
*/
public GHCommitComment createComment(String body, String path, Integer line, Integer position) throws IOException {
GHCommitComment r = new Requester(owner.root)
.with("body",body)
.with("path",path)
.with("line",line)
.with("position",position)
.to(String.format("/repos/%s/%s/commits/%s/comments",owner.getOwnerName(),owner.getName(),sha),GHCommitComment.class);
GHCommitComment r = new Requester(owner.root).with("body", body)
.with("path", path)
.with("line", line)
.with("position", position)
.to(String.format("/repos/%s/%s/commits/%s/comments", owner.getOwnerName(), owner.getName(), sha),
GHCommitComment.class);
return r.wrap(owner);
}
/**
* Create comment gh commit comment.
*
* @param body
* the body
* @return the gh commit comment
* @throws IOException
* the io exception
*/
public GHCommitComment createComment(String body) throws IOException {
return createComment(body, null, null, null);
}
/**
* Gets the status of this commit, newer ones first.
* List statuses paged iterable.
*
* @return status of this commit, newer ones first.
* @throws IOException
* if statuses cannot be read
*/
public PagedIterable<GHCommitStatus> listStatuses() throws IOException {
return owner.listCommitStatuses(sha);
}
/**
* Gets the last status of this commit, which is what gets shown in the UI.
* Gets last status.
*
* @return the last status of this commit, which is what gets shown in the UI.
* @throws IOException
* on error
*/
public GHCommitStatus getLastStatus() throws IOException {
return owner.getLastCommitStatus(sha);
@@ -375,9 +512,12 @@ public class GHCommit {
/**
* Some of the fields are not always filled in when this object is retrieved as a part of another API call.
*
* @throws IOException
* on error
*/
void populate() throws IOException {
if (files==null && stats==null)
if (files == null && stats == null)
owner.root.retrieve().to(owner.getApiTailUrl("commits/" + sha), this);
}

View File

@@ -9,8 +9,7 @@ import java.util.List;
import java.util.TimeZone;
/**
* Builder pattern for creating a new commit.
* Based on https://developer.github.com/v3/git/commits/#create-a-commit
* Builder pattern for creating a new commit. Based on https://developer.github.com/v3/git/commits/#create-a-commit
*/
public class GHCommitBuilder {
private final GHRepository repo;
@@ -39,7 +38,11 @@ public class GHCommitBuilder {
}
/**
* @param message the commit message
* Message gh commit builder.
*
* @param message
* the commit message
* @return the gh commit builder
*/
public GHCommitBuilder message(String message) {
req.with("message", message);
@@ -47,7 +50,11 @@ public class GHCommitBuilder {
}
/**
* @param tree the SHA of the tree object this commit points to
* Tree gh commit builder.
*
* @param tree
* the SHA of the tree object this commit points to
* @return the gh commit builder
*/
public GHCommitBuilder tree(String tree) {
req.with("tree", tree);
@@ -55,7 +62,11 @@ public class GHCommitBuilder {
}
/**
* @param parent the SHA of a parent commit.
* Parent gh commit builder.
*
* @param parent
* the SHA of a parent commit.
* @return the gh commit builder
*/
public GHCommitBuilder parent(String parent) {
parents.add(parent);
@@ -64,17 +75,33 @@ public class GHCommitBuilder {
/**
* Configures the author of this commit.
*
* @param name
* the name
* @param email
* the email
* @param date
* the date
* @return the gh commit builder
*/
public GHCommitBuilder author(String name, String email, Date date) {
req._with("author", new UserInfo(name, email, date));
req.with("author", new UserInfo(name, email, date));
return this;
}
/**
* Configures the committer of this commit.
*
* @param name
* the name
* @param email
* the email
* @param date
* the date
* @return the gh commit builder
*/
public GHCommitBuilder committer(String name, String email, Date date) {
req._with("committer", new UserInfo(name, email, date));
req.with("committer", new UserInfo(name, email, date));
return this;
}
@@ -84,9 +111,13 @@ public class GHCommitBuilder {
/**
* Creates a blob based on the parameters specified thus far.
*
* @return the gh commit
* @throws IOException
* the io exception
*/
public GHCommit create() throws IOException {
req._with("parents", parents);
req.with("parents", parents);
return req.method("POST").to(getApiTail(), GHCommit.class).wrapUp(repo);
}
}

View File

@@ -11,61 +11,83 @@ import static org.kohsuke.github.Previews.*;
* A comment attached to a commit (or a specific line in a specific file of a commit.)
*
* @author Kohsuke Kawaguchi
* @see GHRepository#listCommitComments()
* @see GHCommit#listComments()
* @see GHCommit#createComment(String, String, Integer, Integer)
* @see GHRepository#listCommitComments() GHRepository#listCommitComments()
* @see GHCommit#listComments() GHCommit#listComments()
* @see GHCommit#createComment(String, String, Integer, Integer) GHCommit#createComment(String, String, Integer,
* Integer)
*/
@SuppressFBWarnings(value = {"UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD",
"NP_UNWRITTEN_FIELD"}, justification = "JSON API")
@SuppressFBWarnings(value = { "UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD", "NP_UNWRITTEN_FIELD" },
justification = "JSON API")
public class GHCommitComment extends GHObject implements Reactable {
private GHRepository owner;
String body, html_url, commit_id;
Integer line;
String path;
GHUser user; // not fully populated. beware.
GHUser user; // not fully populated. beware.
/**
* Gets owner.
*
* @return the owner
*/
public GHRepository getOwner() {
return owner;
}
/**
* URL like 'https://github.com/kohsuke/sandbox-ant/commit/8ae38db0ea5837313ab5f39d43a6f73de3bd9000#commitcomment-1252827' to
* URL like
* 'https://github.com/kohsuke/sandbox-ant/commit/8ae38db0ea5837313ab5f39d43a6f73de3bd9000#commitcomment-1252827' to
* show this commit comment in a browser.
*/
public URL getHtmlUrl() {
return GitHub.parseURL(html_url);
}
/**
* Gets sha 1.
*
* @return the sha 1
*/
public String getSHA1() {
return commit_id;
}
/**
* Commit comment in the GitHub flavored markdown format.
*
* @return the body
*/
public String getBody() {
return body;
}
/**
* A commit comment can be on a specific line of a specific file, if so, this field points to a file.
* Otherwise null.
* A commit comment can be on a specific line of a specific file, if so, this field points to a file. Otherwise
* null.
*
* @return the path
*/
public String getPath() {
return path;
}
/**
* A commit comment can be on a specific line of a specific file, if so, this field points to the line number in the file.
* Otherwise -1.
* A commit comment can be on a specific line of a specific file, if so, this field points to the line number in the
* file. Otherwise -1.
*
* @return the line
*/
public int getLine() {
return line!=null ? line : -1;
return line != null ? line : -1;
}
/**
* Gets the user who put this comment.
*
* @return the user
* @throws IOException
* the io exception
*/
public GHUser getUser() throws IOException {
return owner == null || owner.root.isOffline() ? user : owner.root.getUser(user.login);
@@ -73,6 +95,10 @@ public class GHCommitComment extends GHObject implements Reactable {
/**
* Gets the commit to which this comment is associated with.
*
* @return the commit
* @throws IOException
* the io exception
*/
public GHCommit getCommit() throws IOException {
return getOwner().getCommit(getSHA1());
@@ -80,49 +106,48 @@ public class GHCommitComment extends GHObject implements Reactable {
/**
* Updates the body of the commit message.
*
* @param body
* the body
* @throws IOException
* the io exception
*/
public void update(String body) throws IOException {
new Requester(owner.root)
.with("body", body)
.method("PATCH").to(getApiTail(), GHCommitComment.class);
new Requester(owner.root).with("body", body).method("PATCH").to(getApiTail(), GHCommitComment.class);
this.body = body;
}
@Preview @Deprecated
@Preview
@Deprecated
public GHReaction createReaction(ReactionContent content) throws IOException {
return new Requester(owner.root)
.withPreview(SQUIRREL_GIRL)
return new Requester(owner.root).withPreview(SQUIRREL_GIRL)
.with("content", content.getContent())
.to(getApiTail()+"/reactions", GHReaction.class).wrap(owner.root);
.to(getApiTail() + "/reactions", GHReaction.class)
.wrap(owner.root);
}
@Preview @Deprecated
@Preview
@Deprecated
public PagedIterable<GHReaction> listReactions() {
return new PagedIterable<GHReaction>() {
public PagedIterator<GHReaction> _iterator(int pageSize) {
return new PagedIterator<GHReaction>(owner.root.retrieve().withPreview(SQUIRREL_GIRL).asIterator(getApiTail()+"/reactions", GHReaction[].class, pageSize)) {
@Override
protected void wrapUp(GHReaction[] page) {
for (GHReaction c : page)
c.wrap(owner.root);
}
};
}
};
return owner.root.retrieve()
.withPreview(SQUIRREL_GIRL)
.asPagedIterable(getApiTail() + "/reactions", GHReaction[].class, item -> item.wrap(owner.root));
}
/**
* Deletes this comment.
*
* @throws IOException
* the io exception
*/
public void delete() throws IOException {
new Requester(owner.root).method("DELETE").to(getApiTail());
}
private String getApiTail() {
return String.format("/repos/%s/%s/comments/%s",owner.getOwnerName(),owner.getName(),id);
return String.format("/repos/%s/%s/comments/%s", owner.getOwnerName(), owner.getName(), id);
}
GHCommitComment wrap(GHRepository owner) {
this.owner = owner;
if (owner.root.isOffline()) {

View File

@@ -36,16 +36,22 @@ public class GHCommitPointer {
private GHRepository repo;
/**
* This points to the user who owns
* the {@link #getRepository()}.
* This points to the user who owns the {@link #getRepository()}.
*
* @return the user
* @throws IOException
* the io exception
*/
public GHUser getUser() throws IOException {
if (user != null) return user.root.intern(user);
if (user != null)
return user.root.intern(user);
return user;
}
/**
* The repository that contains the commit.
*
* @return the repository
*/
public GHRepository getRepository() {
return repo;
@@ -53,6 +59,8 @@ public class GHCommitPointer {
/**
* Named ref to the commit. This appears to be a "short ref" that doesn't include "refs/heads/" portion.
*
* @return the ref
*/
public String getRef() {
return ref;
@@ -60,6 +68,8 @@ public class GHCommitPointer {
/**
* SHA1 of the commit.
*
* @return the sha
*/
public String getSha() {
return sha;
@@ -67,6 +77,8 @@ public class GHCommitPointer {
/**
* String that looks like "USERNAME:REF".
*
* @return the label
*/
public String getLabel() {
return label;
@@ -74,13 +86,19 @@ public class GHCommitPointer {
/**
* Obtains the commit that this pointer is referring to.
*
* @return the commit
* @throws IOException
* the io exception
*/
public GHCommit getCommit() throws IOException {
return getRepository().getCommit(getSha());
}
void wrapUp(GitHub root) {
if (user!=null) user.root = root;
if (repo!=null) repo.wrap(root);
if (user != null)
user.root = root;
if (repo != null)
repo.wrap(root);
}
}

View File

@@ -16,57 +16,83 @@ import java.util.Date;
* </pre>
*
* @author Kohsuke Kawaguchi
* @see GHRepository#queryCommits()
*/
* @see GHRepository#queryCommits() GHRepository#queryCommits()
*/
public class GHCommitQueryBuilder {
private final Requester req;
private final GHRepository repo;
/*package*/ GHCommitQueryBuilder(GHRepository repo) {
GHCommitQueryBuilder(GHRepository repo) {
this.repo = repo;
this.req = repo.root.retrieve(); // requester to build up
this.req = repo.root.retrieve(); // requester to build up
}
/**
* GItHub login or email address by which to filter by commit author.
*
* @param author
* the author
* @return the gh commit query builder
*/
public GHCommitQueryBuilder author(String author) {
req.with("author",author);
req.with("author", author);
return this;
}
/**
* Only commits containing this file path will be returned.
*
* @param path
* the path
* @return the gh commit query builder
*/
public GHCommitQueryBuilder path(String path) {
req.with("path",path);
req.with("path", path);
return this;
}
/**
* Specifies the SHA1 commit / tag / branch / etc to start listing commits from.
*
* @param ref
* the ref
* @return the gh commit query builder
*/
public GHCommitQueryBuilder from(String ref) {
req.with("sha",ref);
req.with("sha", ref);
return this;
}
/**
* Page size gh commit query builder.
*
* @param pageSize
* the page size
* @return the gh commit query builder
*/
public GHCommitQueryBuilder pageSize(int pageSize) {
req.with("per_page",pageSize);
req.with("per_page", pageSize);
return this;
}
/**
* Only commits after this date will be returned
*
* @param dt
* the dt
* @return the gh commit query builder
*/
public GHCommitQueryBuilder since(Date dt) {
req.with("since",GitHub.printDate(dt));
req.with("since", GitHub.printDate(dt));
return this;
}
/**
* Only commits after this date will be returned
*
* @param timestamp
* the timestamp
* @return the gh commit query builder
*/
public GHCommitQueryBuilder since(long timestamp) {
return since(new Date(timestamp));
@@ -74,14 +100,22 @@ public class GHCommitQueryBuilder {
/**
* Only commits before this date will be returned
*
* @param dt
* the dt
* @return the gh commit query builder
*/
public GHCommitQueryBuilder until(Date dt) {
req.with("until",GitHub.printDate(dt));
req.with("until", GitHub.printDate(dt));
return this;
}
/**
* Only commits before this date will be returned
*
* @param timestamp
* the timestamp
* @return the gh commit query builder
*/
public GHCommitQueryBuilder until(long timestamp) {
return until(new Date(timestamp));
@@ -89,17 +123,10 @@ public class GHCommitQueryBuilder {
/**
* Lists up the commits with the criteria built so far.
*
* @return the paged iterable
*/
public PagedIterable<GHCommit> list() {
return new PagedIterable<GHCommit>() {
public PagedIterator<GHCommit> _iterator(int pageSize) {
return new PagedIterator<GHCommit>(req.asIterator(repo.getApiTailUrl("commits"), GHCommit[].class, pageSize)) {
protected void wrapUp(GHCommit[] page) {
for (GHCommit c : page)
c.wrapUp(repo);
}
};
}
};
return req.asPagedIterable(repo.getApiTailUrl("commits"), GHCommit[].class, item -> item.wrapUp(repo));
}
}

View File

@@ -1,6 +1,6 @@
package org.kohsuke.github;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.StringUtils;
import java.io.IOException;
@@ -8,12 +8,13 @@ import java.io.IOException;
* Search commits.
*
* @author Marc de Verdelhan
* @see GitHub#searchCommits()
* @see GitHub#searchCommits() GitHub#searchCommits()
*/
@Preview @Deprecated
@Preview
@Deprecated
public class GHCommitSearchBuilder extends GHSearchBuilder<GHCommit> {
/*package*/ GHCommitSearchBuilder(GitHub root) {
super(root,CommitSearchResult.class);
GHCommitSearchBuilder(GitHub root) {
super(root, CommitSearchResult.class);
req.withPreview(Previews.CLOAK);
}
@@ -25,100 +26,233 @@ public class GHCommitSearchBuilder extends GHSearchBuilder<GHCommit> {
return this;
}
/**
* Author gh commit search builder.
*
* @param v
* the v
* @return the gh commit search builder
*/
public GHCommitSearchBuilder author(String v) {
return q("author:"+v);
return q("author:" + v);
}
/**
* Committer gh commit search builder.
*
* @param v
* the v
* @return the gh commit search builder
*/
public GHCommitSearchBuilder committer(String v) {
return q("committer:"+v);
return q("committer:" + v);
}
/**
* Author name gh commit search builder.
*
* @param v
* the v
* @return the gh commit search builder
*/
public GHCommitSearchBuilder authorName(String v) {
return q("author-name:"+v);
return q("author-name:" + v);
}
/**
* Committer name gh commit search builder.
*
* @param v
* the v
* @return the gh commit search builder
*/
public GHCommitSearchBuilder committerName(String v) {
return q("committer-name:"+v);
return q("committer-name:" + v);
}
/**
* Author email gh commit search builder.
*
* @param v
* the v
* @return the gh commit search builder
*/
public GHCommitSearchBuilder authorEmail(String v) {
return q("author-email:"+v);
return q("author-email:" + v);
}
/**
* Committer email gh commit search builder.
*
* @param v
* the v
* @return the gh commit search builder
*/
public GHCommitSearchBuilder committerEmail(String v) {
return q("committer-email:"+v);
return q("committer-email:" + v);
}
/**
* Author date gh commit search builder.
*
* @param v
* the v
* @return the gh commit search builder
*/
public GHCommitSearchBuilder authorDate(String v) {
return q("author-date:"+v);
return q("author-date:" + v);
}
/**
* Committer date gh commit search builder.
*
* @param v
* the v
* @return the gh commit search builder
*/
public GHCommitSearchBuilder committerDate(String v) {
return q("committer-date:"+v);
return q("committer-date:" + v);
}
/**
* Merge gh commit search builder.
*
* @param merge
* the merge
* @return the gh commit search builder
*/
public GHCommitSearchBuilder merge(boolean merge) {
return q("merge:"+Boolean.valueOf(merge).toString().toLowerCase());
return q("merge:" + Boolean.valueOf(merge).toString().toLowerCase());
}
/**
* Hash gh commit search builder.
*
* @param v
* the v
* @return the gh commit search builder
*/
public GHCommitSearchBuilder hash(String v) {
return q("hash:"+v);
return q("hash:" + v);
}
/**
* Parent gh commit search builder.
*
* @param v
* the v
* @return the gh commit search builder
*/
public GHCommitSearchBuilder parent(String v) {
return q("parent:"+v);
return q("parent:" + v);
}
/**
* Tree gh commit search builder.
*
* @param v
* the v
* @return the gh commit search builder
*/
public GHCommitSearchBuilder tree(String v) {
return q("tree:"+v);
return q("tree:" + v);
}
/**
* Is gh commit search builder.
*
* @param v
* the v
* @return the gh commit search builder
*/
public GHCommitSearchBuilder is(String v) {
return q("is:"+v);
return q("is:" + v);
}
/**
* User gh commit search builder.
*
* @param v
* the v
* @return the gh commit search builder
*/
public GHCommitSearchBuilder user(String v) {
return q("user:"+v);
return q("user:" + v);
}
/**
* Org gh commit search builder.
*
* @param v
* the v
* @return the gh commit search builder
*/
public GHCommitSearchBuilder org(String v) {
return q("org:"+v);
return q("org:" + v);
}
/**
* Repo gh commit search builder.
*
* @param v
* the v
* @return the gh commit search builder
*/
public GHCommitSearchBuilder repo(String v) {
return q("repo:"+v);
return q("repo:" + v);
}
/**
* Order gh commit search builder.
*
* @param v
* the v
* @return the gh commit search builder
*/
public GHCommitSearchBuilder order(GHDirection v) {
req.with("order",v);
req.with("order", v);
return this;
}
/**
* Sort gh commit search builder.
*
* @param sort
* the sort
* @return the gh commit search builder
*/
public GHCommitSearchBuilder sort(Sort sort) {
req.with("sort",sort);
req.with("sort", sort);
return this;
}
public enum Sort { AUTHOR_DATE, COMMITTER_DATE }
/**
* The enum Sort.
*/
public enum Sort {
AUTHOR_DATE, COMMITTER_DATE
}
private static class CommitSearchResult extends SearchResult<GHCommit> {
private GHCommit[] items;
@Override
/*package*/ GHCommit[] getItems(GitHub root) {
GHCommit[] getItems(GitHub root) {
for (GHCommit commit : items) {
String repoName = getRepoName(commit.url);
try {
GHRepository repo = root.getRepository(repoName);
commit.wrapUp(repo);
} catch (IOException ioe) {}
} catch (IOException ioe) {
}
}
return items;
}
}
/**
* @param commitUrl a commit URL
* @param commitUrl
* a commit URL
* @return the repo name ("username/reponame")
*/
private static String getRepoName(String commitUrl) {

View File

@@ -7,49 +7,75 @@ import java.net.URL;
* Represents a status of a commit.
*
* @author Kohsuke Kawaguchi
* @see GHRepository#getLastCommitStatus(String)
* @see GHCommit#getLastStatus()
* @see GHRepository#createCommitStatus(String, GHCommitState, String, String)
* @see GHRepository#getLastCommitStatus(String) GHRepository#getLastCommitStatus(String)
* @see GHCommit#getLastStatus() GHCommit#getLastStatus()
* @see GHRepository#createCommitStatus(String, GHCommitState, String, String) GHRepository#createCommitStatus(String,
* GHCommitState, String, String)
*/
public class GHCommitStatus extends GHObject {
String state;
String target_url,description;
String target_url, description;
String context;
GHUser creator;
private GitHub root;
/*package*/ GHCommitStatus wrapUp(GitHub root) {
if (creator!=null) creator.wrapUp(root);
GHCommitStatus wrapUp(GitHub root) {
if (creator != null)
creator.wrapUp(root);
this.root = root;
return this;
}
/**
* Gets state.
*
* @return the state
*/
public GHCommitState getState() {
for (GHCommitState s : GHCommitState.values()) {
if (s.name().equalsIgnoreCase(state))
return s;
}
throw new IllegalStateException("Unexpected state: "+state);
throw new IllegalStateException("Unexpected state: " + state);
}
/**
* The URL that this status is linked to.
*
* <p>
* This is the URL specified when creating a commit status.
*
* @return the target url
*/
public String getTargetUrl() {
return target_url;
}
/**
* Gets description.
*
* @return the description
*/
public String getDescription() {
return description;
}
/**
* Gets creator.
*
* @return the creator
* @throws IOException
* the io exception
*/
public GHUser getCreator() throws IOException {
return root.intern(creator);
}
/**
* Gets context.
*
* @return the context
*/
public String getContext() {
return context;
}

View File

@@ -21,52 +21,108 @@ public class GHCompare {
private GHRepository owner;
/**
* Gets url.
*
* @return the url
*/
public URL getUrl() {
return GitHub.parseURL(url);
}
/**
* Gets html url.
*
* @return the html url
*/
public URL getHtmlUrl() {
return GitHub.parseURL(html_url);
}
/**
* Gets permalink url.
*
* @return the permalink url
*/
public URL getPermalinkUrl() {
return GitHub.parseURL(permalink_url);
}
/**
* Gets diff url.
*
* @return the diff url
*/
public URL getDiffUrl() {
return GitHub.parseURL(diff_url);
}
/**
* Gets patch url.
*
* @return the patch url
*/
public URL getPatchUrl() {
return GitHub.parseURL(patch_url);
}
/**
* Gets status.
*
* @return the status
*/
public Status getStatus() {
return status;
}
/**
* Gets ahead by.
*
* @return the ahead by
*/
public int getAheadBy() {
return ahead_by;
}
/**
* Gets behind by.
*
* @return the behind by
*/
public int getBehindBy() {
return behind_by;
}
/**
* Gets total commits.
*
* @return the total commits
*/
public int getTotalCommits() {
return total_commits;
}
/**
* Gets base commit.
*
* @return the base commit
*/
public Commit getBaseCommit() {
return base_commit;
}
/**
* Gets merge base commit.
*
* @return the merge base commit
*/
public Commit getMergeBaseCommit() {
return merge_base_commit;
}
/**
* Gets an array of commits.
*
* @return A copy of the array being stored in the class.
*/
public Commit[] getCommits() {
@@ -74,9 +130,10 @@ public class GHCompare {
System.arraycopy(commits, 0, newValue, 0, commits.length);
return newValue;
}
/**
* Gets an array of commits.
*
* @return A copy of the array being stored in the class.
*/
public GHCommit.File[] getFiles() {
@@ -85,6 +142,13 @@ public class GHCompare {
return newValue;
}
/**
* Wrap gh compare.
*
* @param owner
* the owner
* @return the gh compare
*/
public GHCompare wrap(GHRepository owner) {
this.owner = owner;
for (Commit commit : commits) {
@@ -96,71 +160,126 @@ public class GHCompare {
}
/**
* Compare commits had a child commit element with additional details we want to capture.
* This extenstion of GHCommit provides that.
* Compare commits had a child commit element with additional details we want to capture. This extenstion of
* GHCommit provides that.
*/
@SuppressFBWarnings(value = {"UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD"},
@SuppressFBWarnings(value = { "UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD" },
justification = "JSON API")
public static class Commit extends GHCommit {
private InnerCommit commit;
/**
* Gets commit.
*
* @return the commit
*/
public InnerCommit getCommit() {
return commit;
}
}
/**
* The type InnerCommit.
*/
public static class InnerCommit {
private String url, sha, message;
private User author, committer;
private Tree tree;
/**
* Gets url.
*
* @return the url
*/
public String getUrl() {
return url;
}
/**
* Gets sha.
*
* @return the sha
*/
public String getSha() {
return sha;
}
/**
* Gets message.
*
* @return the message
*/
public String getMessage() {
return message;
}
@WithBridgeMethods(value=User.class,castRequired=true)
/**
* Gets author.
*
* @return the author
*/
@WithBridgeMethods(value = User.class, castRequired = true)
public GitUser getAuthor() {
return author;
}
@WithBridgeMethods(value=User.class,castRequired=true)
/**
* Gets committer.
*
* @return the committer
*/
@WithBridgeMethods(value = User.class, castRequired = true)
public GitUser getCommitter() {
return committer;
}
/**
* Gets tree.
*
* @return the tree
*/
public Tree getTree() {
return tree;
}
}
/**
* The type Tree.
*/
public static class Tree {
private String url, sha;
/**
* Gets url.
*
* @return the url
*/
public String getUrl() {
return url;
}
/**
* Gets sha.
*
* @return the sha
*/
public String getSha() {
return sha;
}
}
/**
* The type User.
*
* @deprecated use {@link GitUser} instead.
*/
public static class User extends GitUser {
}
/**
* The enum Status.
*/
public static enum Status {
behind, ahead, identical, diverged
}

View File

@@ -2,22 +2,24 @@ package org.kohsuke.github;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.IOUtils;
import org.apache.commons.codec.binary.Base64InputStream;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
/**
* A Content of a repository.
*
* @author Alexandre COLLIGNON
* @see GHRepository#getFileContent(String)
* @see GHRepository#getFileContent(String) GHRepository#getFileContent(String)
*/
@SuppressWarnings({"UnusedDeclaration"})
public class GHContent {
@SuppressWarnings({ "UnusedDeclaration" })
public class GHContent implements Refreshable {
/*
In normal use of this class, repository field is set via wrap(),
but in the code search API, there's a nested 'repository' field that gets populated from JSON.
* In normal use of this class, repository field is set via wrap(), but in the code search API, there's a nested
* 'repository' field that gets populated from JSON.
*/
private GHRepository repository;
@@ -31,34 +33,69 @@ public class GHContent {
private String path;
private String content;
private String url; // this is the API url
private String git_url; // this is the Blob url
private String html_url; // this is the UI
private String git_url; // this is the Blob url
private String html_url; // this is the UI
private String download_url;
/**
* Gets owner.
*
* @return the owner
*/
public GHRepository getOwner() {
return repository;
}
/**
* Gets type.
*
* @return the type
*/
public String getType() {
return type;
}
/**
* Gets encoding.
*
* @return the encoding
*/
public String getEncoding() {
return encoding;
}
/**
* Gets size.
*
* @return the size
*/
public long getSize() {
return size;
}
/**
* Gets sha.
*
* @return the sha
*/
public String getSha() {
return sha;
}
/**
* Gets name.
*
* @return the name
*/
public String getName() {
return name;
}
/**
* Gets path.
*
* @return the path
*/
public String getPath() {
return path;
}
@@ -67,12 +104,13 @@ public class GHContent {
* Retrieve the decoded content that is stored at this location.
*
* <p>
* Due to the nature of GitHub's API, you're not guaranteed that
* the content will already be populated, so this may trigger
* network activity, and can throw an IOException.
* Due to the nature of GitHub's API, you're not guaranteed that the content will already be populated, so this may
* trigger network activity, and can throw an IOException.
*
* @deprecated
* Use {@link #read()}
* @return the content
* @throws IOException
* the io exception
* @deprecated Use {@link #read()}
*/
@SuppressFBWarnings("DM_DEFAULT_ENCODING")
public String getContent() throws IOException {
@@ -83,28 +121,42 @@ public class GHContent {
* Retrieve the base64-encoded content that is stored at this location.
*
* <p>
* Due to the nature of GitHub's API, you're not guaranteed that
* the content will already be populated, so this may trigger
* network activity, and can throw an IOException.
* Due to the nature of GitHub's API, you're not guaranteed that the content will already be populated, so this may
* trigger network activity, and can throw an IOException.
*
* @deprecated
* Use {@link #read()}
* @return the encoded content
* @throws IOException
* the io exception
* @deprecated Use {@link #read()}
*/
public String getEncodedContent() throws IOException {
if (content!=null)
return content;
else
return Base64.encodeBase64String(IOUtils.toByteArray(read()));
refresh(content);
return content;
}
/**
* Gets url.
*
* @return the url
*/
public String getUrl() {
return url;
}
/**
* Gets git url.
*
* @return the git url
*/
public String getGitUrl() {
return git_url;
}
/**
* Gets html url.
*
* @return the html url
*/
public String getHtmlUrl() {
return html_url;
}
@@ -112,85 +164,159 @@ public class GHContent {
/**
* Retrieves the actual content stored here.
*/
/**
* Retrieves the actual bytes of the blob.
*
* @return the input stream
* @throws IOException
* the io exception
*/
public InputStream read() throws IOException {
// if the download link is encoded with a token on the query string, the default behavior of POST will fail
return new Requester(root).method("GET").asStream(getDownloadUrl());
refresh(content);
if (encoding.equals("base64")) {
try {
return new Base64InputStream(new ByteArrayInputStream(content.getBytes("US-ASCII")), false);
} catch (UnsupportedEncodingException e) {
throw new AssertionError(e); // US-ASCII is mandatory
}
}
throw new UnsupportedOperationException("Unrecognized encoding: " + encoding);
}
/**
* URL to retrieve the raw content of the file. Null if this is a directory.
*
* @return the download url
* @throws IOException
* the io exception
*/
public String getDownloadUrl() throws IOException {
populate();
refresh(download_url);
return download_url;
}
/**
* Is file boolean.
*
* @return the boolean
*/
public boolean isFile() {
return "file".equals(type);
}
/**
* Is directory boolean.
*
* @return the boolean
*/
public boolean isDirectory() {
return "dir".equals(type);
}
/**
* Fully populate the data by retrieving missing data.
*
* <p>
* Depending on the original API call where this object is created, it may not contain everything.
*
* @throws IOException
* the io exception
*/
protected synchronized void populate() throws IOException {
if (download_url!=null) return; // already populated
root.retrieve().to(url, this);
}
/**
* List immediate children of this directory.
*
* @return the paged iterable
* @throws IOException
* the io exception
*/
public PagedIterable<GHContent> listDirectoryContent() throws IOException {
if (!isDirectory())
throw new IllegalStateException(path+" is not a directory");
throw new IllegalStateException(path + " is not a directory");
return new PagedIterable<GHContent>() {
public PagedIterator<GHContent> _iterator(int pageSize) {
return new PagedIterator<GHContent>(root.retrieve().asIterator(url, GHContent[].class, pageSize)) {
@Override
protected void wrapUp(GHContent[] page) {
GHContent.wrap(page, repository);
}
};
}
};
return root.retrieve().asPagedIterable(url, GHContent[].class, item -> item.wrap(repository));
}
/**
* Update gh content update response.
*
* @param newContent
* the new content
* @param commitMessage
* the commit message
* @return the gh content update response
* @throws IOException
* the io exception
*/
@SuppressFBWarnings("DM_DEFAULT_ENCODING")
public GHContentUpdateResponse update(String newContent, String commitMessage) throws IOException {
return update(newContent.getBytes(), commitMessage, null);
}
/**
* Update gh content update response.
*
* @param newContent
* the new content
* @param commitMessage
* the commit message
* @param branch
* the branch
* @return the gh content update response
* @throws IOException
* the io exception
*/
@SuppressFBWarnings("DM_DEFAULT_ENCODING")
public GHContentUpdateResponse update(String newContent, String commitMessage, String branch) throws IOException {
return update(newContent.getBytes(), commitMessage, branch);
}
/**
* Update gh content update response.
*
* @param newContentBytes
* the new content bytes
* @param commitMessage
* the commit message
* @return the gh content update response
* @throws IOException
* the io exception
*/
public GHContentUpdateResponse update(byte[] newContentBytes, String commitMessage) throws IOException {
return update(newContentBytes, commitMessage, null);
}
public GHContentUpdateResponse update(byte[] newContentBytes, String commitMessage, String branch) throws IOException {
/**
* Update gh content update response.
*
* @param newContentBytes
* the new content bytes
* @param commitMessage
* the commit message
* @param branch
* the branch
* @return the gh content update response
* @throws IOException
* the io exception
*/
public GHContentUpdateResponse update(byte[] newContentBytes, String commitMessage, String branch)
throws IOException {
String encodedContent = Base64.encodeBase64String(newContentBytes);
Requester requester = new Requester(root)
.with("path", path)
.with("message", commitMessage)
.with("sha", sha)
.with("content", encodedContent)
.method("PUT");
Requester requester = new Requester(root).with("path", path)
.with("message", commitMessage)
.with("sha", sha)
.with("content", encodedContent)
.method("PUT");
if (branch != null) {
requester.with("branch", branch);
}
GHContentUpdateResponse response = requester.to(getApiRoute(), GHContentUpdateResponse.class);
GHContentUpdateResponse response = requester.to(getApiRoute(repository, path), GHContentUpdateResponse.class);
response.getContent().wrap(repository);
response.getCommit().wrapUp(repository);
@@ -199,29 +325,48 @@ public class GHContent {
return response;
}
/**
* Delete gh content update response.
*
* @param message
* the message
* @return the gh content update response
* @throws IOException
* the io exception
*/
public GHContentUpdateResponse delete(String message) throws IOException {
return delete(message, null);
}
/**
* Delete gh content update response.
*
* @param commitMessage
* the commit message
* @param branch
* the branch
* @return the gh content update response
* @throws IOException
* the io exception
*/
public GHContentUpdateResponse delete(String commitMessage, String branch) throws IOException {
Requester requester = new Requester(root)
.with("path", path)
.with("message", commitMessage)
.with("sha", sha)
.method("DELETE");
Requester requester = new Requester(root).with("path", path)
.with("message", commitMessage)
.with("sha", sha)
.method("DELETE");
if (branch != null) {
requester.with("branch", branch);
}
GHContentUpdateResponse response = requester.to(getApiRoute(), GHContentUpdateResponse.class);
GHContentUpdateResponse response = requester.to(getApiRoute(repository, path), GHContentUpdateResponse.class);
response.getCommit().wrapUp(repository);
return response;
}
private String getApiRoute() {
return "/repos/" + repository.getOwnerName() + "/" + repository.getName() + "/contents/" + path;
static String getApiRoute(GHRepository repository, String path) {
return repository.getApiTailUrl("contents/" + path);
}
GHContent wrap(GHRepository owner) {
@@ -229,18 +374,37 @@ public class GHContent {
this.root = owner.root;
return this;
}
GHContent wrap(GitHub root) {
this.root = root;
if (repository!=null)
if (repository != null)
repository.wrap(root);
return this;
}
/**
* Wrap gh content [ ].
*
* @param contents
* the contents
* @param repository
* the repository
* @return the gh content [ ]
*/
public static GHContent[] wrap(GHContent[] contents, GHRepository repository) {
for (GHContent unwrappedContent : contents) {
unwrappedContent.wrap(repository);
}
return contents;
}
/**
* Fully populate the data by retrieving missing data.
*
* Depending on the original API call where this object is created, it may not contain everything.
*/
@Override
public synchronized void refresh() throws IOException {
root.retrieve().to(url, this);
}
}

View File

@@ -0,0 +1,118 @@
package org.kohsuke.github;
import org.apache.commons.codec.binary.Base64;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
/**
* Used to create/update content.
*
* <p>
* Call various methods to build up parameters, then call {@link #commit()} to make the change effective.
*
* @author Kohsuke Kawaguchi
* @see GHRepository#createContent() GHRepository#createContent()
*/
public final class GHContentBuilder {
private final GHRepository repo;
private final Requester req;
private String path;
GHContentBuilder(GHRepository repo) {
this.repo = repo;
this.req = new Requester(repo.root).method("PUT");
}
/**
* Path gh content builder.
*
* @param path
* the path
* @return the gh content builder
*/
public GHContentBuilder path(String path) {
this.path = path;
req.with("path", path);
return this;
}
/**
* Branch gh content builder.
*
* @param branch
* the branch
* @return the gh content builder
*/
public GHContentBuilder branch(String branch) {
req.with("branch", branch);
return this;
}
/**
* Used when updating (but not creating a new content) to specify Thetblob SHA of the file being replaced.
*
* @param sha
* the sha
* @return the gh content builder
*/
public GHContentBuilder sha(String sha) {
req.with("sha", sha);
return this;
}
/**
* Content gh content builder.
*
* @param content
* the content
* @return the gh content builder
*/
public GHContentBuilder content(byte[] content) {
req.with("content", Base64.encodeBase64String(content));
return this;
}
/**
* Content gh content builder.
*
* @param content
* the content
* @return the gh content builder
*/
public GHContentBuilder content(String content) {
try {
return content(content.getBytes("UTF-8"));
} catch (UnsupportedEncodingException x) {
throw new AssertionError();
}
}
/**
* Message gh content builder.
*
* @param commitMessage
* the commit message
* @return the gh content builder
*/
public GHContentBuilder message(String commitMessage) {
req.with("message", commitMessage);
return this;
}
/**
* Commits a new content.
*
* @return the gh content update response
* @throws IOException
* the io exception
*/
public GHContentUpdateResponse commit() throws IOException {
GHContentUpdateResponse response = req.to(GHContent.getApiRoute(repo, path), GHContentUpdateResponse.class);
response.getContent().wrap(repo);
response.getCommit().wrapUp(repo);
return response;
}
}

View File

@@ -4,11 +4,11 @@ package org.kohsuke.github;
* Search code for {@link GHContent}.
*
* @author Kohsuke Kawaguchi
* @see GitHub#searchContent()
* @see GitHub#searchContent() GitHub#searchContent()
*/
public class GHContentSearchBuilder extends GHSearchBuilder<GHContent> {
/*package*/ GHContentSearchBuilder(GitHub root) {
super(root,ContentSearchResult.class);
GHContentSearchBuilder(GitHub root) {
super(root, ContentSearchResult.class);
}
/**
@@ -19,48 +19,110 @@ public class GHContentSearchBuilder extends GHSearchBuilder<GHContent> {
return this;
}
/**
* In gh content search builder.
*
* @param v
* the v
* @return the gh content search builder
*/
public GHContentSearchBuilder in(String v) {
return q("in:"+v);
return q("in:" + v);
}
/**
* Language gh content search builder.
*
* @param v
* the v
* @return the gh content search builder
*/
public GHContentSearchBuilder language(String v) {
return q("language:"+v);
return q("language:" + v);
}
/**
* Fork gh content search builder.
*
* @param v
* the v
* @return the gh content search builder
*/
public GHContentSearchBuilder fork(String v) {
return q("fork:"+v);
return q("fork:" + v);
}
/**
* Size gh content search builder.
*
* @param v
* the v
* @return the gh content search builder
*/
public GHContentSearchBuilder size(String v) {
return q("size:"+v);
return q("size:" + v);
}
/**
* Path gh content search builder.
*
* @param v
* the v
* @return the gh content search builder
*/
public GHContentSearchBuilder path(String v) {
return q("path:"+v);
return q("path:" + v);
}
/**
* Filename gh content search builder.
*
* @param v
* the v
* @return the gh content search builder
*/
public GHContentSearchBuilder filename(String v) {
return q("filename:"+v);
return q("filename:" + v);
}
/**
* Extension gh content search builder.
*
* @param v
* the v
* @return the gh content search builder
*/
public GHContentSearchBuilder extension(String v) {
return q("extension:"+v);
return q("extension:" + v);
}
/**
* User gh content search builder.
*
* @param v
* the v
* @return the gh content search builder
*/
public GHContentSearchBuilder user(String v) {
return q("user:"+v);
return q("user:" + v);
}
/**
* Repo gh content search builder.
*
* @param v
* the v
* @return the gh content search builder
*/
public GHContentSearchBuilder repo(String v) {
return q("repo:"+v);
return q("repo:" + v);
}
private static class ContentSearchResult extends SearchResult<GHContent> {
private GHContent[] items;
@Override
/*package*/ GHContent[] getItems(GitHub root) {
GHContent[] getItems(GitHub root) {
for (GHContent item : items)
item.wrap(root);
return items;

View File

@@ -1,17 +1,26 @@
package org.kohsuke.github;
/**
* The response that is returned when updating
* repository content.
**/
* The response that is returned when updating repository content.
*/
public class GHContentUpdateResponse {
private GHContent content;
private GHCommit commit;
/**
* Gets content.
*
* @return the content
*/
public GHContent getContent() {
return content;
}
/**
* Gets commit.
*
* @return the commit
*/
public GHCommit getCommit() {
return commit;
}

View File

@@ -7,14 +7,13 @@ package org.kohsuke.github;
* @see <a href="https://developer.github.com/v3/licenses/#get-a-repositorys-license">documentation</a>
* @see GHRepository#getLicense()
*/
@Preview @Deprecated
class GHContentWithLicense extends GHContent {
GHLicense license;
@Override
GHContentWithLicense wrap(GHRepository owner) {
super.wrap(owner);
if (license!=null)
if (license != null)
license.wrap(owner.root);
return this;
}

View File

@@ -13,123 +13,187 @@ public class GHCreateRepositoryBuilder {
protected final Requester builder;
private final String apiUrlTail;
/*package*/ GHCreateRepositoryBuilder(GitHub root, String apiUrlTail, String name) {
GHCreateRepositoryBuilder(GitHub root, String apiUrlTail, String name) {
this.root = root;
this.apiUrlTail = apiUrlTail;
this.builder = new Requester(root);
this.builder.with("name",name);
this.builder.with("name", name);
}
/**
* Description for repository
*
* @param description
* description of repository
* @return a builder to continue with building
*/
public GHCreateRepositoryBuilder description(String description) {
this.builder.with("description",description);
this.builder.with("description", description);
return this;
}
/**
* Homepage for repository
*
* @param homepage
* homepage of repository
* @return a builder to continue with building
*/
public GHCreateRepositoryBuilder homepage(URL homepage) {
return homepage(homepage.toExternalForm());
}
/**
* Homepage for repository
*
* @param homepage
* homepage of repository
* @return a builder to continue with building
*/
public GHCreateRepositoryBuilder homepage(String homepage) {
this.builder.with("homepage",homepage);
this.builder.with("homepage", homepage);
return this;
}
/**
* Creates a private repository
*
* @param enabled
* private if true
* @return a builder to continue with building
*/
public GHCreateRepositoryBuilder private_(boolean b) {
this.builder.with("private",b);
public GHCreateRepositoryBuilder private_(boolean enabled) {
this.builder.with("private", enabled);
return this;
}
/**
* Enables issue tracker
*
* @param enabled
* true if enabled
* @return a builder to continue with building
*/
public GHCreateRepositoryBuilder issues(boolean b) {
this.builder.with("has_issues",b);
public GHCreateRepositoryBuilder issues(boolean enabled) {
this.builder.with("has_issues", enabled);
return this;
}
/**
* Enables wiki
*
* @param enabled
* true if enabled
* @return a builder to continue with building
*/
public GHCreateRepositoryBuilder wiki(boolean b) {
this.builder.with("has_wiki",b);
public GHCreateRepositoryBuilder wiki(boolean enabled) {
this.builder.with("has_wiki", enabled);
return this;
}
/**
* Enables downloads
*
* @param enabled
* true if enabled
* @return a builder to continue with building
*/
public GHCreateRepositoryBuilder downloads(boolean b) {
this.builder.with("has_downloads",b);
public GHCreateRepositoryBuilder downloads(boolean enabled) {
this.builder.with("has_downloads", enabled);
return this;
}
/**
* If true, create an initial commit with empty README.
*
* @param enabled
* true if enabled
* @return a builder to continue with building
*/
public GHCreateRepositoryBuilder autoInit(boolean b) {
this.builder.with("auto_init",b);
public GHCreateRepositoryBuilder autoInit(boolean enabled) {
this.builder.with("auto_init", enabled);
return this;
}
/**
* Allow or disallow squash-merging pull requests.
*
* @param enabled
* true if enabled
* @return a builder to continue with building
*/
public GHCreateRepositoryBuilder allowSquashMerge(boolean b) {
this.builder.with("allow_squash_merge",b);
public GHCreateRepositoryBuilder allowSquashMerge(boolean enabled) {
this.builder.with("allow_squash_merge", enabled);
return this;
}
/**
* Allow or disallow merging pull requests with a merge commit.
*
* @param enabled
* true if enabled
* @return a builder to continue with building
*/
public GHCreateRepositoryBuilder allowMergeCommit(boolean b) {
this.builder.with("allow_merge_commit",b);
public GHCreateRepositoryBuilder allowMergeCommit(boolean enabled) {
this.builder.with("allow_merge_commit", enabled);
return this;
}
/**
* Allow or disallow rebase-merging pull requests.
*
* @param enabled
* true if enabled
* @return a builder to continue with building
*/
public GHCreateRepositoryBuilder allowRebaseMerge(boolean b) {
this.builder.with("allow_rebase_merge",b);
public GHCreateRepositoryBuilder allowRebaseMerge(boolean enabled) {
this.builder.with("allow_rebase_merge", enabled);
return this;
}
/**
* Creates a default .gitignore
*
* See https://developer.github.com/v3/repos/#create
* @param language
* template to base the ignore file on
* @return a builder to continue with building See https://developer.github.com/v3/repos/#create
*/
public GHCreateRepositoryBuilder gitignoreTemplate(String language) {
this.builder.with("gitignore_template",language);
this.builder.with("gitignore_template", language);
return this;
}
/**
* Desired license template to apply
*
* See https://developer.github.com/v3/repos/#create
* @param license
* template to base the license file on
* @return a builder to continue with building See https://developer.github.com/v3/repos/#create
*/
public GHCreateRepositoryBuilder licenseTemplate(String license) {
this.builder.with("license_template",license);
this.builder.with("license_template", license);
return this;
}
/**
* The team that gets granted access to this repository. Only valid for creating a repository in
* an organization.
* The team that gets granted access to this repository. Only valid for creating a repository in an organization.
*
* @param team
* team to grant access to
* @return a builder to continue with building
*/
public GHCreateRepositoryBuilder team(GHTeam team) {
if (team!=null)
this.builder.with("team_id",team.getId());
if (team != null)
this.builder.with("team_id", team.getId());
return this;
}
/**
* Creates a repository with all the parameters.
*
* @return the gh repository
* @throws IOException
* if repsitory cannot be created
*/
public GHRepository create() throws IOException {
return builder.method("POST").to(apiUrlTail, GHRepository.class).wrap(root);

View File

@@ -1,46 +1,88 @@
package org.kohsuke.github;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringBuilder;
import java.io.IOException;
/**
* The type GHDeployKey.
*/
public class GHDeployKey {
protected String url, key, title;
protected boolean verified;
protected int id;
protected long id;
private GHRepository owner;
public int getId() {
/**
* Gets id.
*
* @return the id
*/
public long getId() {
return id;
}
/**
* Gets key.
*
* @return the key
*/
public String getKey() {
return key;
}
/**
* Gets title.
*
* @return the title
*/
public String getTitle() {
return title;
}
/**
* Gets url.
*
* @return the url
*/
public String getUrl() {
return url;
}
/**
* Is verified boolean.
*
* @return the boolean
*/
public boolean isVerified() {
return verified;
}
/**
* Wrap gh deploy key.
*
* @param repo
* the repo
* @return the gh deploy key
*/
public GHDeployKey wrap(GHRepository repo) {
this.owner = repo;
return this;
}
public String toString() {
return new ToStringBuilder(this).append("title",title).append("id",id).append("key",key).toString();
return new ToStringBuilder(this).append("title", title).append("id", id).append("key", key).toString();
}
/**
* Delete.
*
* @throws IOException
* the io exception
*/
public void delete() throws IOException {
new Requester(owner.root).method("DELETE").to(String.format("/repos/%s/%s/keys/%d", owner.getOwnerName(), owner.getName(), id));
new Requester(owner.root).method("DELETE")
.to(String.format("/repos/%s/%s/keys/%d", owner.getOwnerName(), owner.getName(), id));
}
}

View File

@@ -7,8 +7,9 @@ import java.net.URL;
* Represents a deployment
*
* @see <a href="https://developer.github.com/v3/repos/deployments/">documentation</a>
* @see GHRepository#listDeployments(String, String, String, String)
* @see GHRepository#getDeployment(long)
* @see GHRepository#listDeployments(String, String, String, String) GHRepository#listDeployments(String, String,
* String, String)
* @see GHRepository#getDeployment(long) GHRepository#getDeployment(long)
*/
public class GHDeployment extends GHObject {
private GHRepository owner;
@@ -23,38 +24,85 @@ public class GHDeployment extends GHObject {
protected String repository_url;
protected GHUser creator;
GHDeployment wrap(GHRepository owner) {
this.owner = owner;
this.root = owner.root;
if(creator != null) creator.wrapUp(root);
if (creator != null)
creator.wrapUp(root);
return this;
}
/**
* Gets statuses url.
*
* @return the statuses url
*/
public URL getStatusesUrl() {
return GitHub.parseURL(statuses_url);
}
/**
* Gets repository url.
*
* @return the repository url
*/
public URL getRepositoryUrl() {
return GitHub.parseURL(repository_url);
}
/**
* Gets task.
*
* @return the task
*/
public String getTask() {
return task;
}
/**
* Gets payload.
*
* @return the payload
*/
public String getPayload() {
return (String) payload;
}
/**
* Gets environment.
*
* @return the environment
*/
public String getEnvironment() {
return environment;
}
/**
* Gets creator.
*
* @return the creator
* @throws IOException
* the io exception
*/
public GHUser getCreator() throws IOException {
return root.intern(creator);
}
/**
* Gets ref.
*
* @return the ref
*/
public String getRef() {
return ref;
}
public String getSha(){
/**
* Gets sha.
*
* @return the sha
*/
public String getSha() {
return sha;
}
@@ -66,22 +114,24 @@ public class GHDeployment extends GHObject {
return null;
}
/**
* Create status gh deployment status builder.
*
* @param state
* the state
* @return the gh deployment status builder
*/
public GHDeploymentStatusBuilder createStatus(GHDeploymentState state) {
return new GHDeploymentStatusBuilder(owner,id,state);
return new GHDeploymentStatusBuilder(owner, id, state);
}
/**
* List statuses paged iterable.
*
* @return the paged iterable
*/
public PagedIterable<GHDeploymentStatus> listStatuses() {
return new PagedIterable<GHDeploymentStatus>() {
public PagedIterator<GHDeploymentStatus> _iterator(int pageSize) {
return new PagedIterator<GHDeploymentStatus>(root.retrieve().asIterator(statuses_url, GHDeploymentStatus[].class, pageSize)) {
@Override
protected void wrapUp(GHDeploymentStatus[] page) {
for (GHDeploymentStatus c : page)
c.wrap(owner);
}
};
}
};
return root.retrieve().asPagedIterable(statuses_url, GHDeploymentStatus[].class, item -> item.wrap(owner));
}
}

View File

@@ -3,53 +3,130 @@ package org.kohsuke.github;
import java.io.IOException;
import java.util.List;
//Based on https://developer.github.com/v3/repos/deployments/#create-a-deployment
/**
* The type GHDeploymentBuilder.
*/
// Based on https://developer.github.com/v3/repos/deployments/#create-a-deployment
public class GHDeploymentBuilder {
private final GHRepository repo;
private final Requester builder;
/**
* Instantiates a new Gh deployment builder.
*
* @param repo
* the repo
*/
public GHDeploymentBuilder(GHRepository repo) {
this.repo = repo;
this.builder = new Requester(repo.root);
}
/**
* Instantiates a new Gh deployment builder.
*
* @param repo
* the repo
* @param ref
* the ref
*/
public GHDeploymentBuilder(GHRepository repo, String ref) {
this(repo);
ref(ref);
}
/**
* Ref gh deployment builder.
*
* @param branch
* the branch
* @return the gh deployment builder
*/
public GHDeploymentBuilder ref(String branch) {
builder.with("ref",branch);
builder.with("ref", branch);
return this;
}
/**
* Task gh deployment builder.
*
* @param task
* the task
* @return the gh deployment builder
*/
public GHDeploymentBuilder task(String task) {
builder.with("task",task);
builder.with("task", task);
return this;
}
/**
* Auto merge gh deployment builder.
*
* @param autoMerge
* the auto merge
* @return the gh deployment builder
*/
public GHDeploymentBuilder autoMerge(boolean autoMerge) {
builder.with("auto_merge",autoMerge);
builder.with("auto_merge", autoMerge);
return this;
}
/**
* Required contexts gh deployment builder.
*
* @param requiredContexts
* the required contexts
* @return the gh deployment builder
*/
public GHDeploymentBuilder requiredContexts(List<String> requiredContexts) {
builder.with("required_contexts",requiredContexts);
builder.with("required_contexts", requiredContexts);
return this;
}
/**
* Payload gh deployment builder.
*
* @param payload
* the payload
* @return the gh deployment builder
*/
public GHDeploymentBuilder payload(String payload) {
builder.with("payload",payload);
builder.with("payload", payload);
return this;
}
/**
* Environment gh deployment builder.
*
* @param environment
* the environment
* @return the gh deployment builder
*/
public GHDeploymentBuilder environment(String environment) {
builder.with("environment",environment);
return this;
}
public GHDeploymentBuilder description(String description) {
builder.with("description",description);
builder.with("environment", environment);
return this;
}
/**
* Description gh deployment builder.
*
* @param description
* the description
* @return the gh deployment builder
*/
public GHDeploymentBuilder description(String description) {
builder.with("description", description);
return this;
}
/**
* Create gh deployment.
*
* @return the gh deployment
* @throws IOException
* the io exception
*/
public GHDeployment create() throws IOException {
return builder.to(repo.getApiTailUrl("deployments"),GHDeployment.class).wrap(repo);
return builder.to(repo.getApiTailUrl("deployments"), GHDeployment.class).wrap(repo);
}
}

View File

@@ -3,6 +3,9 @@ package org.kohsuke.github;
import java.net.URL;
import java.util.Locale;
/**
* The type GHDeploymentStatus.
*/
public class GHDeploymentStatus extends GHObject {
private GHRepository owner;
private GitHub root;
@@ -12,24 +15,54 @@ public class GHDeploymentStatus extends GHObject {
protected String target_url;
protected String deployment_url;
protected String repository_url;
/**
* Wrap gh deployment status.
*
* @param owner
* the owner
* @return the gh deployment status
*/
public GHDeploymentStatus wrap(GHRepository owner) {
this.owner = owner;
this.root = owner.root;
if(creator != null) creator.wrapUp(root);
if (creator != null)
creator.wrapUp(root);
return this;
}
/**
* Gets target url.
*
* @return the target url
*/
public URL getTargetUrl() {
return GitHub.parseURL(target_url);
}
/**
* Gets deployment url.
*
* @return the deployment url
*/
public URL getDeploymentUrl() {
return GitHub.parseURL(deployment_url);
}
/**
* Gets repository url.
*
* @return the repository url
*/
public URL getRepositoryUrl() {
return GitHub.parseURL(repository_url);
}
/**
* Gets state.
*
* @return the state
*/
public GHDeploymentState getState() {
return GHDeploymentState.valueOf(state.toUpperCase(Locale.ENGLISH));
}

View File

@@ -5,8 +5,7 @@ import java.io.IOException;
/**
* Creates a new deployment status.
*
* @see
* GHDeployment#createStatus(GHDeploymentState)
* @see GHDeployment#createStatus(GHDeploymentState) GHDeployment#createStatus(GHDeploymentState)
*/
public class GHDeploymentStatusBuilder {
private final Requester builder;
@@ -14,31 +13,60 @@ public class GHDeploymentStatusBuilder {
private long deploymentId;
/**
* @deprecated
* Use {@link GHDeployment#createStatus(GHDeploymentState)}
* Instantiates a new Gh deployment status builder.
*
* @param repo
* the repo
* @param deploymentId
* the deployment id
* @param state
* the state
* @deprecated Use {@link GHDeployment#createStatus(GHDeploymentState)}
*/
public GHDeploymentStatusBuilder(GHRepository repo, int deploymentId, GHDeploymentState state) {
this(repo,(long)deploymentId,state);
this(repo, (long) deploymentId, state);
}
/*package*/ GHDeploymentStatusBuilder(GHRepository repo, long deploymentId, GHDeploymentState state) {
GHDeploymentStatusBuilder(GHRepository repo, long deploymentId, GHDeploymentState state) {
this.repo = repo;
this.deploymentId = deploymentId;
this.builder = new Requester(repo.root);
this.builder.with("state",state);
this.builder.with("state", state);
}
/**
* Description gh deployment status builder.
*
* @param description
* the description
* @return the gh deployment status builder
*/
public GHDeploymentStatusBuilder description(String description) {
this.builder.with("description",description);
return this;
}
public GHDeploymentStatusBuilder targetUrl(String targetUrl) {
this.builder.with("target_url",targetUrl);
this.builder.with("description", description);
return this;
}
/**
* Target url gh deployment status builder.
*
* @param targetUrl
* the target url
* @return the gh deployment status builder
*/
public GHDeploymentStatusBuilder targetUrl(String targetUrl) {
this.builder.with("target_url", targetUrl);
return this;
}
/**
* Create gh deployment status.
*
* @return the gh deployment status
* @throws IOException
* the io exception
*/
public GHDeploymentStatus create() throws IOException {
return builder.to(repo.getApiTailUrl("deployments/"+deploymentId+"/statuses"),GHDeploymentStatus.class).wrap(repo);
return builder.to(repo.getApiTailUrl("deployments/" + deploymentId + "/statuses"), GHDeploymentStatus.class)
.wrap(repo);
}
}

View File

@@ -25,36 +25,51 @@ package org.kohsuke.github;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
/**
* Represents an email of GitHub.
*
* @author Kelly Campbell
*/
@SuppressFBWarnings(value = {"UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD",
"NP_UNWRITTEN_FIELD", "NP_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD"}, justification = "JSON API")
@SuppressFBWarnings(
value = { "UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD", "NP_UNWRITTEN_FIELD",
"NP_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD" },
justification = "JSON API")
public class GHEmail {
protected String email;
protected boolean primary;
protected boolean verified;
/**
* Gets email.
*
* @return the email
*/
public String getEmail() {
return email;
}
/**
* Is primary boolean.
*
* @return the boolean
*/
public boolean isPrimary() {
return primary;
}
/**
* Is verified boolean.
*
* @return the boolean
*/
public boolean isVerified() {
return verified;
}
@Override
public String toString() {
return "Email:"+email;
return "Email:" + email;
}
@Override

View File

@@ -23,6 +23,8 @@ public enum GHEvent {
GOLLUM,
INSTALLATION,
INSTALLATION_REPOSITORIES,
INTEGRATION_INSTALLATION_REPOSITORIES,
CHECK_SUITE,
ISSUE_COMMENT,
ISSUES,
LABEL,
@@ -42,7 +44,11 @@ public enum GHEvent {
PULL_REQUEST_REVIEW_COMMENT,
PUSH,
RELEASE,
REPOSITORY, // only valid for org hooks
REPOSITORY, // only
// valid
// for
// org
// hooks
STATUS,
TEAM,
TEAM_ADD,
@@ -53,12 +59,12 @@ public enum GHEvent {
*/
ALL;
/**
* Returns GitHub's internal representation of this event.
*/
String symbol() {
if (this==ALL) return "*";
if (this == ALL)
return "*";
return name().toLowerCase(Locale.ENGLISH);
}
}

View File

@@ -30,73 +30,118 @@ public class GHEventInfo {
/**
* Inside the event JSON model, GitHub uses a slightly different format.
*/
@SuppressFBWarnings(value = {"UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD",
"UWF_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR" }, justification = "JSON API")
@SuppressFBWarnings(
value = { "UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD",
"UWF_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR" },
justification = "JSON API")
public static class GHEventRepository {
@SuppressFBWarnings(value = "UUF_UNUSED_FIELD", justification = "We don't provide it in API now")
private int id;
private long id;
@SuppressFBWarnings(value = "UUF_UNUSED_FIELD", justification = "We don't provide it in API now")
private String url; // repository API URL
private String name; // owner/repo
private String url; // repository API URL
private String name; // owner/repo
}
/**
* Gets type.
*
* @return the type
*/
public GHEvent getType() {
String t = type;
if (t.endsWith("Event")) t=t.substring(0,t.length()-5);
if (t.endsWith("Event"))
t = t.substring(0, t.length() - 5);
for (GHEvent e : GHEvent.values()) {
if (e.name().replace("_","").equalsIgnoreCase(t))
if (e.name().replace("_", "").equalsIgnoreCase(t))
return e;
}
return null; // unknown event type
return null; // unknown event type
}
/*package*/ GHEventInfo wrapUp(GitHub root) {
GHEventInfo wrapUp(GitHub root) {
this.root = root;
return this;
}
/**
* Gets id.
*
* @return the id
*/
public long getId() {
return id;
}
/**
* Gets created at.
*
* @return the created at
*/
public Date getCreatedAt() {
return GitHub.parseDate(created_at);
}
/**
* Repository where the change was made.
* Gets repository.
*
* @return Repository where the change was made.
* @throws IOException
* on error
*/
@SuppressFBWarnings(value = {"UWF_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR" },
@SuppressFBWarnings(value = { "UWF_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR" },
justification = "The field comes from JSON deserialization")
public GHRepository getRepository() throws IOException {
return root.getRepository(repo.name);
}
@SuppressFBWarnings(value = {"UWF_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR" },
/**
* Gets actor.
*
* @return the {@link GHUser} actor for this event.
* @throws IOException
* on error
*/
@SuppressFBWarnings(value = { "UWF_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR" },
justification = "The field comes from JSON deserialization")
public GHUser getActor() throws IOException {
return root.getUser(actor.getLogin());
}
/**
* Quick way to just get the actor of the login.
* Gets actor login.
*
* @return the login of the actor.
* @throws IOException
* on error
*/
public String getActorLogin() throws IOException {
return actor.getLogin();
}
@SuppressFBWarnings(value = {"UWF_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR" },
/**
* Gets organization.
*
* @return the organization
* @throws IOException
* the io exception
*/
@SuppressFBWarnings(value = { "UWF_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR" },
justification = "The field comes from JSON deserialization")
public GHOrganization getOrganization() throws IOException {
return (org==null || org.getLogin()==null) ? null : root.getOrganization(org.getLogin());
return (org == null || org.getLogin() == null) ? null : root.getOrganization(org.getLogin());
}
/**
* Retrieves the payload.
*
*
* @param <T>
* the type parameter
* @param type
* Specify one of the {@link GHEventPayload} subtype that defines a type-safe access to the payload.
* This must match the {@linkplain #getType() event type}.
* Specify one of the {@link GHEventPayload} subtype that defines a type-safe access to the payload. This
* must match the {@linkplain #getType() event type}.
* @return parsed event payload
* @throws IOException
* if payload cannot be parsed
*/
public <T extends GHEventPayload> T getPayload(Class<T> type) throws IOException {
T v = GitHub.MAPPER.readValue(payload.traverse(), type);

File diff suppressed because it is too large Load Diff

View File

@@ -1,13 +1,29 @@
package org.kohsuke.github;
/**
* The type GHException.
*
* @author Kohsuke Kawaguchi
*/
public class GHException extends RuntimeException {
/**
* Instantiates a new Gh exception.
*
* @param message
* the message
*/
public GHException(String message) {
super(message);
}
/**
* Instantiates a new Gh exception.
*
* @param message
* the message
* @param cause
* the cause
*/
public GHException(String message, Throwable cause) {
super(message, cause);
}

View File

@@ -1,27 +1,41 @@
package org.kohsuke.github;
import javax.annotation.CheckForNull;
import java.io.FileNotFoundException;
import java.net.HttpURLConnection;
import java.util.List;
import java.util.Map;
import javax.annotation.CheckForNull;
/**
* Request/responce contains useful metadata.
* Custom exception allows store info for next diagnostics.
* Request/responce contains useful metadata. Custom exception allows store info for next diagnostics.
*
* @author Kanstantsin Shautsou
*/
public class GHFileNotFoundException extends FileNotFoundException {
protected Map<String, List<String>> responseHeaderFields;
/**
* Instantiates a new Gh file not found exception.
*/
public GHFileNotFoundException() {
}
/**
* Instantiates a new Gh file not found exception.
*
* @param s
* the s
*/
public GHFileNotFoundException(String s) {
super(s);
}
/**
* Gets response header fields.
*
* @return the response header fields
*/
@CheckForNull
public Map<String, List<String>> getResponseHeaderFields() {
return responseHeaderFields;

View File

@@ -1,6 +1,7 @@
package org.kohsuke.github;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.apache.commons.lang3.StringUtils;
import java.io.IOException;
import java.net.URL;
@@ -13,14 +14,14 @@ import java.util.Map.Entry;
* Gist
*
* @author Kohsuke Kawaguchi
* @see GHUser#listGists()
* @see GitHub#getGist(String)
* @see GitHub#createGist()
* @see GHUser#listGists() GHUser#listGists()
* @see GitHub#getGist(String) GitHub#getGist(String)
* @see GitHub#createGist() GitHub#createGist()
* @see <a href="https://developer.github.com/v3/gists/">documentation</a>
*/
public class GHGist extends GHObject {
/*package almost final*/ GHUser owner;
/*package almost final*/ GitHub root;
/* package almost final */ GHUser owner;
/* package almost final */ GitHub root;
private String forks_url, commits_url, id, git_pull_url, git_push_url, html_url;
@@ -33,30 +34,51 @@ public class GHGist extends GHObject {
private String comments_url;
private Map<String,GHGistFile> files = new HashMap<String, GHGistFile>();
private Map<String, GHGistFile> files = new HashMap<String, GHGistFile>();
/**
* User that owns this Gist.
* Gets owner.
*
* @return User that owns this Gist.
* @throws IOException
* the io exception
*/
public GHUser getOwner() throws IOException {
return root.intern(owner);
}
/**
* Gets forks url.
*
* @return the forks url
*/
public String getForksUrl() {
return forks_url;
}
/**
* Gets commits url.
*
* @return the commits url
*/
public String getCommitsUrl() {
return commits_url;
}
/**
* URL like https://gist.github.com/gists/12345.git
* Gets git pull url.
*
* @return URL like https://gist.github.com/gists/12345.git
*/
public String getGitPullUrl() {
return git_pull_url;
}
/**
* Gets git push url.
*
* @return the git push url
*/
public String getGitPushUrl() {
return git_push_url;
}
@@ -65,34 +87,63 @@ public class GHGist extends GHObject {
return GitHub.parseURL(html_url);
}
/**
* Is public boolean.
*
* @return the boolean
*/
public boolean isPublic() {
return _public;
}
/**
* Gets description.
*
* @return the description
*/
public String getDescription() {
return description;
}
/**
* Gets comment count.
*
* @return the comment count
*/
public int getCommentCount() {
return comments;
}
/**
* API URL of listing comments.
* Gets comments url.
*
* @return API URL of listing comments.
*/
public String getCommentsUrl() {
return comments_url;
}
/**
* Gets file.
*
* @param name
* the name
* @return the file
*/
public GHGistFile getFile(String name) {
return files.get(name);
}
public Map<String,GHGistFile> getFiles() {
/**
* Gets files.
*
* @return the files
*/
public Map<String, GHGistFile> getFiles() {
return Collections.unmodifiableMap(files);
}
/*package*/ GHGist wrapUp(GHUser owner) {
GHGist wrapUp(GHUser owner) {
this.owner = owner;
this.root = owner.root;
wrapUp();
@@ -100,10 +151,10 @@ public class GHGist extends GHObject {
}
/**
* Used when caller obtains {@link GHGist} without knowing its owner.
* A partially constructed owner object is interned.
* Used when caller obtains {@link GHGist} without knowing its owner. A partially constructed owner object is
* interned.
*/
/*package*/ GHGist wrapUp(GitHub root) {
GHGist wrapUp(GitHub root) {
this.owner = root.getUser(owner);
this.root = root;
wrapUp();
@@ -115,54 +166,93 @@ public class GHGist extends GHObject {
e.getValue().fileName = e.getKey();
}
}
String getApiTailUrl(String tail) {
return "/gists/" + id + '/' + tail;
String result = "/gists/" + id;
if (!StringUtils.isBlank(tail)) {
result += StringUtils.prependIfMissing(tail, "/");
}
return result;
}
/**
* Star.
*
* @throws IOException
* the io exception
*/
public void star() throws IOException {
new Requester(root).method("PUT").to(getApiTailUrl("star"));
}
/**
* Unstar.
*
* @throws IOException
* the io exception
*/
public void unstar() throws IOException {
new Requester(root).method("DELETE").to(getApiTailUrl("star"));
}
/**
* Is starred boolean.
*
* @return the boolean
* @throws IOException
* the io exception
*/
public boolean isStarred() throws IOException {
return root.retrieve().asHttpStatusCode(getApiTailUrl("star"))/100==2;
return root.retrieve().asHttpStatusCode(getApiTailUrl("star")) / 100 == 2;
}
/**
* Forks this gist into your own.
*
* @return the gh gist
* @throws IOException
* the io exception
*/
public GHGist fork() throws IOException {
return new Requester(root).to(getApiTailUrl("forks"),GHGist.class).wrapUp(root);
return new Requester(root).to(getApiTailUrl("forks"), GHGist.class).wrapUp(root);
}
/**
* List forks paged iterable.
*
* @return the paged iterable
*/
public PagedIterable<GHGist> listForks() {
return new PagedIterable<GHGist>() {
public PagedIterator<GHGist> _iterator(int pageSize) {
return new PagedIterator<GHGist>(root.retrieve().asIterator(getApiTailUrl("forks"), GHGist[].class, pageSize)) {
@Override
protected void wrapUp(GHGist[] page) {
for (GHGist c : page)
c.wrapUp(root);
}
};
}
};
return root.retrieve().asPagedIterable(getApiTailUrl("forks"), GHGist[].class, item -> item.wrapUp(root));
}
/**
* Deletes this gist.
*
* @throws IOException
* the io exception
*/
public void delete() throws IOException {
new Requester(root).method("DELETE").to("/gists/" + id);
}
/**
* Updates this gist via a builder.
*
* @return the gh gist updater
* @throws IOException
* the io exception
*/
public GHGistUpdater update() throws IOException {
return new GHGistUpdater(this);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
GHGist ghGist = (GHGist) o;
return id.equals(ghGist.id);
@@ -172,4 +262,10 @@ public class GHGist extends GHObject {
public int hashCode() {
return id.hashCode();
}
GHGist wrap(GHUser owner) {
this.owner = owner;
this.root = owner.root;
return this;
}
}

View File

@@ -8,30 +8,56 @@ import java.util.LinkedHashMap;
* Builder pattern for creating a new Gist.
*
* @author Kohsuke Kawaguchi
* @see GitHub#createGist()
* @see GitHub#createGist() GitHub#createGist()
*/
public class GHGistBuilder {
private final GitHub root;
private final Requester req;
private final LinkedHashMap<String,Object> files = new LinkedHashMap<String, Object>();
private final LinkedHashMap<String, Object> files = new LinkedHashMap<String, Object>();
/**
* Instantiates a new Gh gist builder.
*
* @param root
* the root
*/
public GHGistBuilder(GitHub root) {
this.root = root;
req = new Requester(root);
}
/**
* Description gh gist builder.
*
* @param desc
* the desc
* @return the gh gist builder
*/
public GHGistBuilder description(String desc) {
req.with("description",desc);
return this;
}
public GHGistBuilder public_(boolean v) {
req.with("public",v);
req.with("description", desc);
return this;
}
/**
* Adds a new file.
* Public gh gist builder.
*
* @param v
* the v
* @return the gh gist builder
*/
public GHGistBuilder public_(boolean v) {
req.with("public", v);
return this;
}
/**
* File gh gist builder.
*
* @param fileName
* the file name
* @param content
* the content
* @return Adds a new file.
*/
public GHGistBuilder file(String fileName, String content) {
files.put(fileName, Collections.singletonMap("content", content));
@@ -40,9 +66,13 @@ public class GHGistBuilder {
/**
* Creates a Gist based on the parameters specified thus far.
*
* @return created Gist
* @throws IOException
* if Gist cannot be created.
*/
public GHGist create() throws IOException {
req._with("files",files);
return req.to("/gists",GHGist.class).wrapUp(root);
req.with("files", files);
return req.to("/gists", GHGist.class).wrapUp(root);
}
}

View File

@@ -4,23 +4,29 @@ package org.kohsuke.github;
* A file inside {@link GHGist}
*
* @author Kohsuke Kawaguchi
* @see GHGist#getFile(String)
* @see GHGist#getFiles()
* @see GHGist#getFile(String) GHGist#getFile(String)
* @see GHGist#getFiles() GHGist#getFiles()
*/
public class GHGistFile {
/*package almost final*/ String fileName;
/* package almost final */ String fileName;
private int size;
private String raw_url, type, language, content;
private boolean truncated;
/**
* Gets file name.
*
* @return the file name
*/
public String getFileName() {
return fileName;
}
/**
* File size in bytes.
*
* @return the size
*/
public int getSize() {
return size;
@@ -28,6 +34,8 @@ public class GHGistFile {
/**
* URL that serves this file as-is.
*
* @return the raw url
*/
public String getRawUrl() {
return raw_url;
@@ -35,17 +43,26 @@ public class GHGistFile {
/**
* Content type of this Gist, such as "text/plain"
*
* @return the type
*/
public String getType() {
return type;
}
/**
* Gets language.
*
* @return the language
*/
public String getLanguage() {
return language;
}
/**
* Content of this file.
*
* @return the content
*/
public String getContent() {
return content;
@@ -53,6 +70,8 @@ public class GHGistFile {
/**
* (?) indicates if {@link #getContent()} contains a truncated content.
*
* @return the boolean
*/
public boolean isTruncated() {
return truncated;

View File

@@ -0,0 +1,101 @@
package org.kohsuke.github;
import java.io.IOException;
import java.util.Collections;
import java.util.LinkedHashMap;
/**
* Builder pattern for updating a Gist.
*
* @author Martin van Zijl
*/
public class GHGistUpdater {
private final GHGist base;
private final Requester builder;
LinkedHashMap<String, Object> files;
GHGistUpdater(GHGist base) {
this.base = base;
this.builder = new Requester(base.root);
files = new LinkedHashMap<>();
}
/**
* Add file gh gist updater.
*
* @param fileName
* the file name
* @param content
* the content
* @return the gh gist updater
* @throws IOException
* the io exception
*/
public GHGistUpdater addFile(String fileName, String content) throws IOException {
updateFile(fileName, content);
return this;
}
// // This method does not work.
// public GHGistUpdater deleteFile(String fileName) throws IOException {
// files.put(fileName, Collections.singletonMap("filename", null));
// return this;
// }
/**
* Rename file gh gist updater.
*
* @param fileName
* the file name
* @param newFileName
* the new file name
* @return the gh gist updater
* @throws IOException
* the io exception
*/
public GHGistUpdater renameFile(String fileName, String newFileName) throws IOException {
files.put(fileName, Collections.singletonMap("filename", newFileName));
return this;
}
/**
* Update file gh gist updater.
*
* @param fileName
* the file name
* @param content
* the content
* @return the gh gist updater
* @throws IOException
* the io exception
*/
public GHGistUpdater updateFile(String fileName, String content) throws IOException {
files.put(fileName, Collections.singletonMap("content", content));
return this;
}
/**
* Description gh gist updater.
*
* @param desc
* the desc
* @return the gh gist updater
*/
public GHGistUpdater description(String desc) {
builder.with("description", desc);
return this;
}
/**
* Updates the Gist based on the parameters specified thus far.
*
* @return the gh gist
* @throws IOException
* the io exception
*/
public GHGist update() throws IOException {
builder.with("files", files);
return builder.method("PATCH").to(base.getApiTailUrl(""), GHGist.class).wrap(base.owner);
}
}

View File

@@ -11,38 +11,66 @@ import java.util.Locale;
import java.util.Map;
/**
* The type GHHook.
*
* @author Kohsuke Kawaguchi
*/
@SuppressFBWarnings(value = {"UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD",
"NP_UNWRITTEN_FIELD"}, justification = "JSON API")
@SuppressFBWarnings(value = { "UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD", "NP_UNWRITTEN_FIELD" },
justification = "JSON API")
public abstract class GHHook extends GHObject {
String name;
List<String> events;
boolean active;
Map<String,String> config;
Map<String, String> config;
/**
* Gets name.
*
* @return the name
*/
public String getName() {
return name;
}
/**
* Gets events.
*
* @return the events
*/
public EnumSet<GHEvent> getEvents() {
EnumSet<GHEvent> s = EnumSet.noneOf(GHEvent.class);
for (String e : events) {
if (e.equals("*")) s.add(GHEvent.ALL);
else s.add(Enum.valueOf(GHEvent.class, e.toUpperCase(Locale.ENGLISH)));
if (e.equals("*"))
s.add(GHEvent.ALL);
else
s.add(Enum.valueOf(GHEvent.class, e.toUpperCase(Locale.ENGLISH)));
}
return s;
}
/**
* Is active boolean.
*
* @return the boolean
*/
public boolean isActive() {
return active;
}
/**
* Gets config.
*
* @return the config
*/
public Map<String, String> getConfig() {
return Collections.unmodifiableMap(config);
}
/**
* Ping.
*
* @throws IOException
* the io exception
* @see <a href="https://developer.github.com/v3/repos/hooks/#ping-a-hook">Ping hook</a>
*/
public void ping() throws IOException {
@@ -51,6 +79,9 @@ public abstract class GHHook extends GHObject {
/**
* Deletes this hook.
*
* @throws IOException
* the io exception
*/
public void delete() throws IOException {
new Requester(getRoot()).method("DELETE").to(getApiRoute());

View File

@@ -16,37 +16,69 @@ class GHHooks {
private final GitHub root;
private Context(GitHub root) {
this.root = root;
this.root = root;
}
/**
* Gets hooks.
*
* @return the hooks
* @throws IOException
* the io exception
*/
public List<GHHook> getHooks() throws IOException {
GHHook [] hookArray = root.retrieve().to(collection(),collectionClass()); // jdk/eclipse bug requires this to be on separate line
GHHook[] hookArray = root.retrieve().to(collection(), collectionClass()); // jdk/eclipse bug requires this
// to be on separate line
List<GHHook> list = new ArrayList<GHHook>(Arrays.asList(hookArray));
for (GHHook h : list)
wrap(h);
wrap(h);
return list;
}
/**
* Gets hook.
*
* @param id
* the id
* @return the hook
* @throws IOException
* the io exception
*/
public GHHook getHook(int id) throws IOException {
GHHook hook = root.retrieve().to(collection() + "/" + id, clazz());
return wrap(hook);
}
public GHHook createHook(String name, Map<String, String> config, Collection<GHEvent> events, boolean active) throws IOException {
/**
* Create hook gh hook.
*
* @param name
* the name
* @param config
* the config
* @param events
* the events
* @param active
* the active
* @return the gh hook
* @throws IOException
* the io exception
*/
public GHHook createHook(String name, Map<String, String> config, Collection<GHEvent> events, boolean active)
throws IOException {
List<String> ea = null;
if (events!=null) {
ea = new ArrayList<String>();
for (GHEvent e : events)
ea.add(e.symbol());
if (events != null) {
ea = new ArrayList<String>();
for (GHEvent e : events)
ea.add(e.symbol());
}
GHHook hook = new Requester(root)
.with("name", name)
.with("active", active)
._with("config", config)
._with("events", ea)
.to(collection(), clazz());
GHHook hook = new Requester(root).with("name", name)
.with("active", active)
.with("config", config)
.with("events", ea)
.to(collection(), clazz());
return wrap(hook);
}
@@ -87,7 +119,7 @@ class GHHooks {
@Override
GHHook wrap(GHHook hook) {
return ((GHRepoHook)hook).wrap(repository);
return ((GHRepoHook) hook).wrap(repository);
}
}
@@ -116,15 +148,15 @@ class GHHooks {
@Override
GHHook wrap(GHHook hook) {
return ((GHOrgHook)hook).wrap(organization);
return ((GHOrgHook) hook).wrap(organization);
}
}
static Context repoContext(GHRepository repository, GHUser owner) {
return new RepoContext(repository, owner);
}
static Context repoContext(GHRepository repository, GHUser owner) {
return new RepoContext(repository, owner);
}
static Context orgContext(GHOrganization organization) {
return new OrgContext(organization);
}
static Context orgContext(GHOrganization organization) {
return new OrgContext(organization);
}
}

View File

@@ -1,27 +1,41 @@
package org.kohsuke.github;
import javax.annotation.CheckForNull;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.util.List;
import java.util.Map;
import javax.annotation.CheckForNull;
/**
* Request/responce contains useful metadata.
* Custom exception allows store info for next diagnostics.
* Request/responce contains useful metadata. Custom exception allows store info for next diagnostics.
*
* @author Kanstantsin Shautsou
*/
public class GHIOException extends IOException {
protected Map<String, List<String>> responseHeaderFields;
/**
* Instantiates a new Ghio exception.
*/
public GHIOException() {
}
/**
* Instantiates a new Ghio exception.
*
* @param message
* the message
*/
public GHIOException(String message) {
super(message);
}
/**
* Gets response header fields.
*
* @return the response header fields
*/
@CheckForNull
public Map<String, List<String>> getResponseHeaderFields() {
return responseHeaderFields;

View File

@@ -0,0 +1,56 @@
package org.kohsuke.github;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.io.IOException;
import java.net.URL;
/**
* The type GHInvitation.
*
* @see GitHub#getMyInvitations() GitHub#getMyInvitations()
* @see GHRepository#listInvitations() GHRepository#listInvitations()
*/
@SuppressFBWarnings(
value = { "UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD", "NP_UNWRITTEN_FIELD",
"UUF_UNUSED_FIELD" },
justification = "JSON API")
public class GHInvitation extends GHObject {
/* package almost final */ GitHub root;
private int id;
private GHRepository repository;
private GHUser invitee, inviter;
private String permissions;
private String html_url;
GHInvitation wrapUp(GitHub root) {
this.root = root;
return this;
}
/**
* Accept a repository invitation.
*
* @throws IOException
* the io exception
*/
public void accept() throws IOException {
root.retrieve().method("PATCH").to("/user/repository_invitations/" + id);
}
/**
* Decline a repository invitation.
*
* @throws IOException
* the io exception
*/
public void decline() throws IOException {
root.retrieve().method("DELETE").to("/user/repository_invitations/" + id);
}
@Override
public URL getHtmlUrl() {
return GitHub.parseURL(html_url);
}
}

View File

@@ -37,23 +37,25 @@ import java.util.Date;
import java.util.List;
import java.util.Locale;
import static org.kohsuke.github.Previews.*;
import static org.kohsuke.github.Previews.SQUIRREL_GIRL;
/**
* Represents an issue on GitHub.
*
* @author Eric Maupin
* @author Kohsuke Kawaguchi
* @see GHRepository#getIssue(int)
* @see GitHub#searchIssues()
* @see GHRepository#getIssue(int) GHRepository#getIssue(int)
* @see GitHub#searchIssues() GitHub#searchIssues()
* @see GHIssueSearchBuilder
*/
public class GHIssue extends GHObject implements Reactable{
public class GHIssue extends GHObject implements Reactable {
private static final String ASSIGNEES = "assignees";
GitHub root;
GHRepository owner;
// API v3
protected GHUser assignee; // not sure what this field is now that 'assignees' exist
protected GHUser assignee; // not sure what this field is now that 'assignees' exist
protected GHUser[] assignees;
protected String state;
protected int number;
@@ -71,27 +73,34 @@ public class GHIssue extends GHObject implements Reactable{
protected boolean locked;
/**
* The type Label.
*
* @deprecated use {@link GHLabel}
*/
public static class Label extends GHLabel {
}
/*package*/ GHIssue wrap(GHRepository owner) {
GHIssue wrap(GHRepository owner) {
this.owner = owner;
if(milestone != null) milestone.wrap(owner);
if (milestone != null)
milestone.wrap(owner);
return wrap(owner.root);
}
/*package*/ GHIssue wrap(GitHub root) {
GHIssue wrap(GitHub root) {
this.root = root;
if(assignee != null) assignee.wrapUp(root);
if(assignees!=null) GHUser.wrap(assignees,root);
if(user != null) user.wrapUp(root);
if(closed_by != null) closed_by.wrapUp(root);
if (assignee != null)
assignee.wrapUp(root);
if (assignees != null)
GHUser.wrap(assignees, root);
if (user != null)
user.wrapUp(root);
if (closed_by != null)
closed_by.wrapUp(root);
return this;
}
/*package*/ static GHIssue[] wrap(GHIssue[] issues, GHRepository owner) {
static GHIssue[] wrap(GHIssue[] issues, GHRepository owner) {
for (GHIssue i : issues)
i.wrap(owner);
return issues;
@@ -99,6 +108,8 @@ public class GHIssue extends GHObject implements Reactable{
/**
* Repository to which the issue belongs.
*
* @return the repository
*/
public GHRepository getRepository() {
return owner;
@@ -106,6 +117,8 @@ public class GHIssue extends GHObject implements Reactable{
/**
* The description of this pull request.
*
* @return the body
*/
public String getBody() {
return body;
@@ -113,76 +126,128 @@ public class GHIssue extends GHObject implements Reactable{
/**
* ID.
*
* @return the number
*/
public int getNumber() {
return number;
}
/**
* The HTML page of this issue,
* like https://github.com/jenkinsci/jenkins/issues/100
* The HTML page of this issue, like https://github.com/jenkinsci/jenkins/issues/100
*/
public URL getHtmlUrl() {
return GitHub.parseURL(html_url);
}
/**
* Gets title.
*
* @return the title
*/
public String getTitle() {
return title;
}
/**
* Is locked boolean.
*
* @return the boolean
*/
public boolean isLocked() {
return locked;
}
/**
* Gets state.
*
* @return the state
*/
public GHIssueState getState() {
return Enum.valueOf(GHIssueState.class, state.toUpperCase(Locale.ENGLISH));
}
/**
* Gets labels.
*
* @return the labels
* @throws IOException
* the io exception
*/
public Collection<GHLabel> getLabels() throws IOException {
if(labels == null){
if (labels == null) {
return Collections.emptyList();
}
return Collections.<GHLabel>unmodifiableList(labels);
}
/**
* Gets closed at.
*
* @return the closed at
*/
public Date getClosedAt() {
return GitHub.parseDate(closed_at);
}
public URL getApiURL(){
/**
* Gets api url.
*
* @return the api url
*/
public URL getApiURL() {
return GitHub.parseURL(url);
}
/**
* Lock.
*
* @throws IOException
* the io exception
*/
public void lock() throws IOException {
new Requester(root).method("PUT").to(getApiRoute()+"/lock");
new Requester(root).method("PUT").to(getApiRoute() + "/lock");
}
/**
* Unlock.
*
* @throws IOException
* the io exception
*/
public void unlock() throws IOException {
new Requester(root).method("PUT").to(getApiRoute()+"/lock");
new Requester(root).method("PUT").to(getApiRoute() + "/lock");
}
/**
* Updates the issue by adding a comment.
*
* @return
* Newly posted comment.
* @param message
* the message
* @return Newly posted comment.
* @throws IOException
* the io exception
*/
@WithBridgeMethods(void.class)
public GHIssueComment comment(String message) throws IOException {
GHIssueComment r = new Requester(root).with("body",message).to(getIssuesApiRoute() + "/comments", GHIssueComment.class);
GHIssueComment r = new Requester(root).with("body", message)
.to(getIssuesApiRoute() + "/comments", GHIssueComment.class);
return r.wrapUp(this);
}
private void edit(String key, Object value) throws IOException {
new Requester(root)._with(key, value).method("PATCH").to(getApiRoute());
new Requester(root).with(key, value).method("PATCH").to(getApiRoute());
}
private void editIssue(String key, Object value) throws IOException {
new Requester(root)._with(key, value).method("PATCH").to(getIssuesApiRoute());
new Requester(root).with(key, value).method("PATCH").to(getIssuesApiRoute());
}
/**
* Closes this issue.
*
* @throws IOException
* the io exception
*/
public void close() throws IOException {
edit("state", "closed");
@@ -190,131 +255,339 @@ public class GHIssue extends GHObject implements Reactable{
/**
* Reopens this issue.
*
* @throws IOException
* the io exception
*/
public void reopen() throws IOException {
edit("state", "open");
}
/**
* Sets title.
*
* @param title
* the title
* @throws IOException
* the io exception
*/
public void setTitle(String title) throws IOException {
edit("title",title);
edit("title", title);
}
/**
* Sets body.
*
* @param body
* the body
* @throws IOException
* the io exception
*/
public void setBody(String body) throws IOException {
edit("body",body);
edit("body", body);
}
/**
* Sets milestone.
*
* @param milestone
* the milestone
* @throws IOException
* the io exception
*/
public void setMilestone(GHMilestone milestone) throws IOException {
edit("milestone",milestone.getNumber());
edit("milestone", milestone.getNumber());
}
/**
* Assign to.
*
* @param user
* the user
* @throws IOException
* the io exception
*/
public void assignTo(GHUser user) throws IOException {
setAssignees(user);
}
/**
* Sets labels.
*
* @param labels
* the labels
* @throws IOException
* the io exception
*/
public void setLabels(String... labels) throws IOException {
editIssue("labels",labels);
editIssue("labels", labels);
}
/**
* Adds labels to the issue.
*
* @param names
* Names of the label
* @throws IOException
* the io exception
*/
public void addLabels(String... names) throws IOException {
_addLabels(Arrays.asList(names));
}
/**
* Add labels.
*
* @param labels
* the labels
* @throws IOException
* the io exception
*/
public void addLabels(GHLabel... labels) throws IOException {
addLabels(Arrays.asList(labels));
}
/**
* Add labels.
*
* @param labels
* the labels
* @throws IOException
* the io exception
*/
public void addLabels(Collection<GHLabel> labels) throws IOException {
_addLabels(GHLabel.toNames(labels));
}
private void _addLabels(Collection<String> names) throws IOException {
List<String> newLabels = new ArrayList<String>();
for (GHLabel label : getLabels()) {
newLabels.add(label.getName());
}
for (String name : names) {
if (!newLabels.contains(name)) {
newLabels.add(name);
}
}
setLabels(newLabels.toArray(new String[0]));
}
/**
* Remove a given label by name from this issue.
*
* @param names
* the names
* @throws IOException
* the io exception
*/
public void removeLabels(String... names) throws IOException {
_removeLabels(Arrays.asList(names));
}
/**
* Remove labels.
*
* @param labels
* the labels
* @throws IOException
* the io exception
* @see #removeLabels(String...) #removeLabels(String...)
*/
public void removeLabels(GHLabel... labels) throws IOException {
removeLabels(Arrays.asList(labels));
}
/**
* Remove labels.
*
* @param labels
* the labels
* @throws IOException
* the io exception
*/
public void removeLabels(Collection<GHLabel> labels) throws IOException {
_removeLabels(GHLabel.toNames(labels));
}
private void _removeLabels(Collection<String> names) throws IOException {
List<String> newLabels = new ArrayList<String>();
for (GHLabel l : getLabels()) {
if (!names.contains(l.getName())) {
newLabels.add(l.getName());
}
}
setLabels(newLabels.toArray(new String[0]));
}
/**
* Obtains all the comments associated with this issue.
*
* @see #listComments()
*
* @return the comments
* @throws IOException
* the io exception
* @see #listComments() #listComments()
*/
public List<GHIssueComment> getComments() throws IOException {
return listComments().asList();
}
/**
* Obtains all the comments associated with this issue.
*
* @return the paged iterable
* @throws IOException
* the io exception
*/
public PagedIterable<GHIssueComment> listComments() throws IOException {
return new PagedIterable<GHIssueComment>() {
public PagedIterator<GHIssueComment> _iterator(int pageSize) {
return new PagedIterator<GHIssueComment>(root.retrieve().asIterator(getIssuesApiRoute() + "/comments", GHIssueComment[].class, pageSize)) {
protected void wrapUp(GHIssueComment[] page) {
for (GHIssueComment c : page)
c.wrapUp(GHIssue.this);
}
};
}
};
return root.retrieve()
.asPagedIterable(getIssuesApiRoute() + "/comments",
GHIssueComment[].class,
item -> item.wrapUp(GHIssue.this));
}
@Preview @Deprecated
@Preview
@Deprecated
public GHReaction createReaction(ReactionContent content) throws IOException {
return new Requester(owner.root)
.withPreview(SQUIRREL_GIRL)
return new Requester(owner.root).withPreview(SQUIRREL_GIRL)
.with("content", content.getContent())
.to(getApiRoute()+"/reactions", GHReaction.class).wrap(root);
.to(getApiRoute() + "/reactions", GHReaction.class)
.wrap(root);
}
@Preview @Deprecated
@Preview
@Deprecated
public PagedIterable<GHReaction> listReactions() {
return new PagedIterable<GHReaction>() {
public PagedIterator<GHReaction> _iterator(int pageSize) {
return new PagedIterator<GHReaction>(owner.root.retrieve().withPreview(SQUIRREL_GIRL).asIterator(getApiRoute()+"/reactions", GHReaction[].class, pageSize)) {
@Override
protected void wrapUp(GHReaction[] page) {
for (GHReaction c : page)
c.wrap(owner.root);
}
};
}
};
return owner.root.retrieve()
.withPreview(SQUIRREL_GIRL)
.asPagedIterable(getApiRoute() + "/reactions", GHReaction[].class, item -> item.wrap(owner.root));
}
/**
* Add assignees.
*
* @param assignees
* the assignees
* @throws IOException
* the io exception
*/
public void addAssignees(GHUser... assignees) throws IOException {
addAssignees(Arrays.asList(assignees));
}
/**
* Add assignees.
*
* @param assignees
* the assignees
* @throws IOException
* the io exception
*/
public void addAssignees(Collection<GHUser> assignees) throws IOException {
List<String> names = toLogins(assignees);
root.retrieve().method("POST").with("assignees",names).to(getIssuesApiRoute()+"/assignees",this);
root.retrieve()
.method("POST")
.with(ASSIGNEES, getLogins(assignees))
.to(getIssuesApiRoute() + "/assignees", this);
}
/**
* Sets assignees.
*
* @param assignees
* the assignees
* @throws IOException
* the io exception
*/
public void setAssignees(GHUser... assignees) throws IOException {
setAssignees(Arrays.asList(assignees));
}
/**
* Sets assignees.
*
* @param assignees
* the assignees
* @throws IOException
* the io exception
*/
public void setAssignees(Collection<GHUser> assignees) throws IOException {
editIssue("assignees",toLogins(assignees));
new Requester(root).with(ASSIGNEES, getLogins(assignees)).method("PATCH").to(getIssuesApiRoute());
}
/**
* Remove assignees.
*
* @param assignees
* the assignees
* @throws IOException
* the io exception
*/
public void removeAssignees(GHUser... assignees) throws IOException {
removeAssignees(Arrays.asList(assignees));
}
/**
* Remove assignees.
*
* @param assignees
* the assignees
* @throws IOException
* the io exception
*/
public void removeAssignees(Collection<GHUser> assignees) throws IOException {
List<String> names = toLogins(assignees);
root.retrieve().method("DELETE").with("assignees",names).inBody().to(getIssuesApiRoute()+"/assignees",this);
}
private List<String> toLogins(Collection<GHUser> assignees) {
List<String> names = new ArrayList<String>(assignees.size());
for (GHUser a : assignees) {
names.add(a.getLogin());
}
return names;
root.retrieve()
.method("DELETE")
.with(ASSIGNEES, getLogins(assignees))
.inBody()
.to(getIssuesApiRoute() + "/assignees", this);
}
/**
* Gets api route.
*
* @return the api route
*/
protected String getApiRoute() {
return getIssuesApiRoute();
}
/**
* Gets issues api route.
*
* @return the issues api route
*/
protected String getIssuesApiRoute() {
return "/repos/"+owner.getOwnerName()+"/"+owner.getName()+"/issues/"+number;
return "/repos/" + owner.getOwnerName() + "/" + owner.getName() + "/issues/" + number;
}
/**
* Gets assignee.
*
* @return the assignee
* @throws IOException
* the io exception
*/
public GHUser getAssignee() throws IOException {
return root.intern(assignee);
}
/**
* Gets assignees.
*
* @return the assignees
*/
public List<GHUser> getAssignees() {
return Collections.unmodifiableList(Arrays.asList(assignees));
}
/**
* User who submitted the issue.
*
* @return the user
* @throws IOException
* the io exception
*/
public GHUser getUser() throws IOException {
return root.intern(user);
@@ -324,56 +597,115 @@ public class GHIssue extends GHObject implements Reactable{
* Reports who has closed the issue.
*
* <p>
* Note that GitHub doesn't always seem to report this information
* even for an issue that's already closed. See
* Note that GitHub doesn't always seem to report this information even for an issue that's already closed. See
* https://github.com/kohsuke/github-api/issues/60.
*
* @return the closed by
* @throws IOException
* the io exception
*/
public GHUser getClosedBy() throws IOException {
if(!"closed".equals(state)) return null;
if (!"closed".equals(state))
return null;
//TODO
// TODO
/*
if (closed_by==null) {
closed_by = owner.getIssue(number).getClosed_by();
}
*/
* if (closed_by==null) { closed_by = owner.getIssue(number).getClosed_by(); }
*/
return root.intern(closed_by);
}
public int getCommentsCount(){
/**
* Gets comments count.
*
* @return the comments count
*/
public int getCommentsCount() {
return comments;
}
/**
* Returns non-null if this issue is a shadow of a pull request.
*
* @return the pull request
*/
public PullRequest getPullRequest() {
return pull_request;
}
/**
* Is pull request boolean.
*
* @return the boolean
*/
public boolean isPullRequest() {
return pull_request!=null;
return pull_request != null;
}
/**
* Gets milestone.
*
* @return the milestone
*/
public GHMilestone getMilestone() {
return milestone;
}
@SuppressFBWarnings(value = {"UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD"},
justification = "JSON API")
public static class PullRequest{
/**
* The type PullRequest.
*/
@SuppressFBWarnings(value = { "UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD" },
justification = "JSON API")
public static class PullRequest {
private String diff_url, patch_url, html_url;
/**
* Gets diff url.
*
* @return the diff url
*/
public URL getDiffUrl() {
return GitHub.parseURL(diff_url);
}
/**
* Gets patch url.
*
* @return the patch url
*/
public URL getPatchUrl() {
return GitHub.parseURL(patch_url);
}
/**
* Gets url.
*
* @return the url
*/
public URL getUrl() {
return GitHub.parseURL(html_url);
}
}
protected static List<String> getLogins(Collection<GHUser> users) {
List<String> names = new ArrayList<String>(users.size());
for (GHUser a : users) {
names.add(a.getLogin());
}
return names;
}
/**
* Lists events for this issue. See https://developer.github.com/v3/issues/events/
*
* @return the paged iterable
* @throws IOException
* the io exception
*/
public PagedIterable<GHIssueEvent> listEvents() throws IOException {
return root.retrieve()
.asPagedIterable(owner.getApiTailUrl(String.format("/issues/%s/events", number)),
GHIssueEvent[].class,
item -> item.wrapUp(GHIssue.this));
}
}

View File

@@ -5,6 +5,8 @@ import java.util.ArrayList;
import java.util.List;
/**
* The type GHIssueBuilder.
*
* @author Kohsuke Kawaguchi
*/
public class GHIssueBuilder {
@@ -16,45 +18,84 @@ public class GHIssueBuilder {
GHIssueBuilder(GHRepository repo, String title) {
this.repo = repo;
this.builder = new Requester(repo.root);
builder.with("title",title);
builder.with("title", title);
}
/**
* Sets the main text of an issue, which is arbitrary multi-line text.
*
* @param str
* the str
* @return the gh issue builder
*/
public GHIssueBuilder body(String str) {
builder.with("body",str);
builder.with("body", str);
return this;
}
/**
* Assignee gh issue builder.
*
* @param user
* the user
* @return the gh issue builder
*/
public GHIssueBuilder assignee(GHUser user) {
if (user!=null)
if (user != null)
assignees.add(user.getLogin());
return this;
}
/**
* Assignee gh issue builder.
*
* @param user
* the user
* @return the gh issue builder
*/
public GHIssueBuilder assignee(String user) {
if (user!=null)
if (user != null)
assignees.add(user);
return this;
}
/**
* Milestone gh issue builder.
*
* @param milestone
* the milestone
* @return the gh issue builder
*/
public GHIssueBuilder milestone(GHMilestone milestone) {
if (milestone!=null)
builder.with("milestone",milestone.getNumber());
if (milestone != null)
builder.with("milestone", milestone.getNumber());
return this;
}
/**
* Label gh issue builder.
*
* @param label
* the label
* @return the gh issue builder
*/
public GHIssueBuilder label(String label) {
if (label!=null)
if (label != null)
labels.add(label);
return this;
}
/**
* Creates a new issue.
*
* @return the gh issue
* @throws IOException
* the io exception
*/
public GHIssue create() throws IOException {
return builder.with("labels",labels).with("assignees",assignees).to(repo.getApiTailUrl("issues"),GHIssue.class).wrap(repo);
return builder.with("labels", labels)
.with("assignees", assignees)
.to(repo.getApiTailUrl("issues"), GHIssue.class)
.wrap(repo);
}
}

View File

@@ -32,20 +32,24 @@ import static org.kohsuke.github.Previews.*;
* Comment to the issue
*
* @author Kohsuke Kawaguchi
* @see GHIssue#comment(String) GHIssue#comment(String)
* @see GHIssue#listComments() GHIssue#listComments()
*/
public class GHIssueComment extends GHObject implements Reactable {
GHIssue owner;
private String body, gravatar_id;
private String body, gravatar_id, html_url, author_association;
private GHUser user; // not fully populated. beware.
/*package*/ GHIssueComment wrapUp(GHIssue owner) {
GHIssueComment wrapUp(GHIssue owner) {
this.owner = owner;
return this;
}
/**
* Gets the issue to which this comment is associated.
*
* @return the parent
*/
public GHIssue getParent() {
return owner;
@@ -53,6 +57,8 @@ public class GHIssueComment extends GHObject implements Reactable {
/**
* The comment itself.
*
* @return the body
*/
public String getBody() {
return body;
@@ -60,6 +66,8 @@ public class GHIssueComment extends GHObject implements Reactable {
/**
* Gets the ID of the user who posted this comment.
*
* @return the user name
*/
@Deprecated
public String getUserName() {
@@ -68,21 +76,36 @@ public class GHIssueComment extends GHObject implements Reactable {
/**
* Gets the user who posted this comment.
*
* @return the user
* @throws IOException
* the io exception
*/
public GHUser getUser() throws IOException {
return owner == null || owner.root.isOffline() ? user : owner.root.getUser(user.getLogin());
}
/**
* @deprecated This object has no HTML URL.
*/
@Override
public URL getHtmlUrl() {
return null;
return GitHub.parseURL(html_url);
}
/**
* Gets author association.
*
* @return the author association
*/
public GHCommentAuthorAssociation getAuthorAssociation() {
return GHCommentAuthorAssociation.valueOf(author_association);
}
/**
* Updates the body of the issue comment.
*
* @param body
* the body
* @throws IOException
* the io exception
*/
public void update(String body) throws IOException {
new Requester(owner.root).with("body", body).method("PATCH").to(getApiRoute(), GHIssueComment.class);
@@ -91,35 +114,33 @@ public class GHIssueComment extends GHObject implements Reactable {
/**
* Deletes this issue comment.
*
* @throws IOException
* the io exception
*/
public void delete() throws IOException {
new Requester(owner.root).method("DELETE").to(getApiRoute());
}
@Preview @Deprecated
@Preview
@Deprecated
public GHReaction createReaction(ReactionContent content) throws IOException {
return new Requester(owner.root)
.withPreview(SQUIRREL_GIRL)
return new Requester(owner.root).withPreview(SQUIRREL_GIRL)
.with("content", content.getContent())
.to(getApiRoute()+"/reactions", GHReaction.class).wrap(owner.root);
.to(getApiRoute() + "/reactions", GHReaction.class)
.wrap(owner.root);
}
@Preview @Deprecated
@Preview
@Deprecated
public PagedIterable<GHReaction> listReactions() {
return new PagedIterable<GHReaction>() {
public PagedIterator<GHReaction> _iterator(int pageSize) {
return new PagedIterator<GHReaction>(owner.root.retrieve().withPreview(SQUIRREL_GIRL).asIterator(getApiRoute()+"/reactions", GHReaction[].class, pageSize)) {
@Override
protected void wrapUp(GHReaction[] page) {
for (GHReaction c : page)
c.wrap(owner.root);
}
};
}
};
return owner.root.retrieve()
.withPreview(SQUIRREL_GIRL)
.asPagedIterable(getApiRoute() + "/reactions", GHReaction[].class, item -> item.wrap(owner.root));
}
private String getApiRoute() {
return "/repos/"+owner.getRepository().getOwnerName()+"/"+owner.getRepository().getName()+"/issues/comments/" + id;
return "/repos/" + owner.getRepository().getOwnerName() + "/" + owner.getRepository().getName()
+ "/issues/comments/" + id;
}
}

View File

@@ -0,0 +1,133 @@
package org.kohsuke.github;
import java.util.Date;
/**
* The type GHIssueEvent.
*
* @author Martin van Zijl
*/
public class GHIssueEvent {
private GitHub root;
private long id;
private String node_id;
private String url;
private GHUser actor;
private String event;
private String commit_id;
private String commit_url;
private String created_at;
private GHIssue issue;
/**
* Gets id.
*
* @return the id
*/
public long getId() {
return id;
}
/**
* Gets node id.
*
* @return the node id
*/
public String getNodeId() {
return node_id;
}
/**
* Gets url.
*
* @return the url
*/
public String getUrl() {
return url;
}
/**
* Gets actor.
*
* @return the actor
*/
public GHUser getActor() {
return actor;
}
/**
* Gets event.
*
* @return the event
*/
public String getEvent() {
return event;
}
/**
* Gets commit id.
*
* @return the commit id
*/
public String getCommitId() {
return commit_id;
}
/**
* Gets commit url.
*
* @return the commit url
*/
public String getCommitUrl() {
return commit_url;
}
/**
* Gets created at.
*
* @return the created at
*/
public Date getCreatedAt() {
return GitHub.parseDate(created_at);
}
/**
* Gets root.
*
* @return the root
*/
public GitHub getRoot() {
return root;
}
/**
* Gets issue.
*
* @return the issue
*/
public GHIssue getIssue() {
return issue;
}
GHIssueEvent wrapUp(GitHub root) {
this.root = root;
return this;
}
GHIssueEvent wrapUp(GHIssue parent) {
this.issue = parent;
this.root = parent.root;
return this;
}
@Override
public String toString() {
return String.format("Issue %d was %s by %s on %s",
getIssue().getNumber(),
getEvent(),
getActor().getLogin(),
getCreatedAt().toString());
}
}

View File

@@ -4,11 +4,11 @@ package org.kohsuke.github;
* Search issues.
*
* @author Kohsuke Kawaguchi
* @see GitHub#searchIssues()
* @see GitHub#searchIssues() GitHub#searchIssues()
*/
public class GHIssueSearchBuilder extends GHSearchBuilder<GHIssue> {
/*package*/ GHIssueSearchBuilder(GitHub root) {
super(root,IssueSearchResult.class);
GHIssueSearchBuilder(GitHub root) {
super(root, IssueSearchResult.class);
}
/**
@@ -19,43 +19,91 @@ public class GHIssueSearchBuilder extends GHSearchBuilder<GHIssue> {
return this;
}
/**
* Mentions gh issue search builder.
*
* @param u
* the u
* @return the gh issue search builder
*/
public GHIssueSearchBuilder mentions(GHUser u) {
return mentions(u.getLogin());
}
/**
* Mentions gh issue search builder.
*
* @param login
* the login
* @return the gh issue search builder
*/
public GHIssueSearchBuilder mentions(String login) {
return q("mentions:"+login);
return q("mentions:" + login);
}
/**
* Is open gh issue search builder.
*
* @return the gh issue search builder
*/
public GHIssueSearchBuilder isOpen() {
return q("is:open");
}
/**
* Is closed gh issue search builder.
*
* @return the gh issue search builder
*/
public GHIssueSearchBuilder isClosed() {
return q("is:closed");
}
/**
* Is merged gh issue search builder.
*
* @return the gh issue search builder
*/
public GHIssueSearchBuilder isMerged() {
return q("is:merged");
}
/**
* Order gh issue search builder.
*
* @param v
* the v
* @return the gh issue search builder
*/
public GHIssueSearchBuilder order(GHDirection v) {
req.with("order",v);
req.with("order", v);
return this;
}
/**
* Sort gh issue search builder.
*
* @param sort
* the sort
* @return the gh issue search builder
*/
public GHIssueSearchBuilder sort(Sort sort) {
req.with("sort",sort);
req.with("sort", sort);
return this;
}
public enum Sort { COMMENTS, CREATED, UPDATED }
/**
* The enum Sort.
*/
public enum Sort {
COMMENTS, CREATED, UPDATED
}
private static class IssueSearchResult extends SearchResult<GHIssue> {
private GHIssue[] items;
@Override
/*package*/ GHIssue[] getItems(GitHub root) {
GHIssue[] getItems(GitHub root) {
for (GHIssue i : items)
i.wrap(root);
return items;

View File

@@ -25,10 +25,10 @@
package org.kohsuke.github;
/**
* @see GHPullRequestQueryBuilder#state(GHIssueState)
* The enum GHIssueState.
*
* @see GHPullRequestQueryBuilder#state(GHIssueState) GHPullRequestQueryBuilder#state(GHIssueState)
*/
public enum GHIssueState {
OPEN,
CLOSED,
ALL
OPEN, CLOSED, ALL
}

View File

@@ -1,7 +1,7 @@
package org.kohsuke.github;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringBuilder;
/**
* SSH public key.
@@ -10,45 +10,72 @@ import org.apache.commons.lang.builder.ToStringBuilder;
*/
@SuppressFBWarnings(value = "UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", justification = "JSON API")
public class GHKey {
/*package almost final*/ GitHub root;
/* package almost final */ GitHub root;
protected String url, key, title;
protected boolean verified;
protected int id;
/**
* Gets id.
*
* @return the id
*/
public int getId() {
return id;
}
/**
* Gets key.
*
* @return the key
*/
public String getKey() {
return key;
}
/**
* Gets title.
*
* @return the title
*/
public String getTitle() {
return title;
}
/**
* Something like "https://api.github.com/user/keys/73593"
*
* @return the url
*/
public String getUrl() {
return url;
}
/**
* Gets root.
*
* @return the root
*/
public GitHub getRoot() {
return root;
}
/**
* Is verified boolean.
*
* @return the boolean
*/
public boolean isVerified() {
return verified;
}
/*package*/ GHKey wrap(GitHub root) {
GHKey wrap(GitHub root) {
this.root = root;
return this;
}
public String toString() {
return new ToStringBuilder(this).append("title",title).append("id",id).append("key",key).toString();
return new ToStringBuilder(this).append("title", title).append("id", id).append("key", key).toString();
}
}

View File

@@ -1,45 +1,136 @@
package org.kohsuke.github;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import static org.kohsuke.github.Previews.SYMMETRA;
/**
* The type GHLabel.
*
* @author Kohsuke Kawaguchi
* @see GHIssue#getLabels()
* @see GHRepository#listLabels()
* @see GHIssue#getLabels() GHIssue#getLabels()
* @see GHRepository#listLabels() GHRepository#listLabels()
*/
public class GHLabel {
private String url, name, color;
private String url, name, color, description;
private GHRepository repo;
/**
* Gets url.
*
* @return the url
*/
public String getUrl() {
return url;
}
/**
* Gets name.
*
* @return the name
*/
public String getName() {
return name;
}
/**
* Color code without leading '#', such as 'f29513'
*
* @return the color
*/
public String getColor() {
return color;
}
/*package*/ GHLabel wrapUp(GHRepository repo) {
/**
* Purpose of Label
*
* @return the description
*/
@Preview
@Deprecated
public String getDescription() {
return description;
}
GHLabel wrapUp(GHRepository repo) {
this.repo = repo;
return this;
}
/**
* Delete.
*
* @throws IOException
* the io exception
*/
public void delete() throws IOException {
repo.root.retrieve().method("DELETE").to(url);
}
/**
* Sets color.
*
* @param newColor
* 6-letter hex color code, like "f29513"
* 6-letter hex color code, like "f29513"
* @throws IOException
* the io exception
*/
public void setColor(String newColor) throws IOException {
repo.root.retrieve().method("PATCH").with("name", name).with("color", newColor).to(url);
repo.root.retrieve()
.method("PATCH")
.withPreview(SYMMETRA)
.with("name", name)
.with("color", newColor)
.with("description", description)
.to(url);
}
/**
* Sets description.
*
* @param newDescription
* Description of label
* @throws IOException
* the io exception
*/
@Preview
@Deprecated
public void setDescription(String newDescription) throws IOException {
repo.root.retrieve()
.method("PATCH")
.withPreview(SYMMETRA)
.with("name", name)
.with("color", color)
.with("description", newDescription)
.to(url);
}
static Collection<String> toNames(Collection<GHLabel> labels) {
List<String> r = new ArrayList<String>();
for (GHLabel l : labels) {
r.add(l.getName());
}
return r;
}
@Override
public boolean equals(final Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
final GHLabel ghLabel = (GHLabel) o;
return Objects.equals(url, ghLabel.url) && Objects.equals(name, ghLabel.name)
&& Objects.equals(color, ghLabel.color) && Objects.equals(repo, ghLabel.repo);
}
@Override
public int hashCode() {
return Objects.hash(url, name, color, repo);
}
}

View File

@@ -32,25 +32,21 @@ import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import static org.kohsuke.github.Previews.*;
/**
* The GitHub Preview API's license information
* <p>
* WARNING: This uses a PREVIEW API - subject to change.
*
* @author Duncan Dickinson
* @see GitHub#getLicense(String)
* @see GHRepository#getLicense()
* @see GitHub#getLicense(String) GitHub#getLicense(String)
* @see GHRepository#getLicense() GHRepository#getLicense()
* @see <a href="https://developer.github.com/v3/licenses/">https://developer.github.com/v3/licenses/</a>
*/
@Preview @Deprecated
@SuppressWarnings({"UnusedDeclaration"})
@SuppressFBWarnings(value = {"UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD",
"NP_UNWRITTEN_FIELD"}, justification = "JSON API")
@SuppressWarnings({ "UnusedDeclaration" })
@SuppressFBWarnings(value = { "UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD", "NP_UNWRITTEN_FIELD" },
justification = "JSON API")
public class GHLicense extends GHObject {
@SuppressFBWarnings("IS2_INCONSISTENT_SYNC") // root is set before the object is returned to the app
/*package almost final*/ GitHub root;
@SuppressFBWarnings("IS2_INCONSISTENT_SYNC")
// root is set before the object is returned to the app
/* package almost final */ GitHub root;
// these fields are always present, even in the short form
protected String key, name;
@@ -65,6 +61,8 @@ public class GHLicense extends GHObject {
protected List<String> forbidden = new ArrayList<String>();
/**
* Gets key.
*
* @return a mnemonic for the license
*/
public String getKey() {
@@ -72,6 +70,8 @@ public class GHLicense extends GHObject {
}
/**
* Gets name.
*
* @return the license name
*/
public String getName() {
@@ -90,6 +90,8 @@ public class GHLicense extends GHObject {
* Featured licenses are bold in the new repository drop-down
*
* @return True if the license is featured, false otherwise
* @throws IOException
* the io exception
*/
public Boolean isFeatured() throws IOException {
populate();
@@ -101,36 +103,85 @@ public class GHLicense extends GHObject {
return GitHub.parseURL(html_url);
}
/**
* Gets description.
*
* @return the description
* @throws IOException
* the io exception
*/
public String getDescription() throws IOException {
populate();
return description;
}
/**
* Gets category.
*
* @return the category
* @throws IOException
* the io exception
*/
public String getCategory() throws IOException {
populate();
return category;
}
/**
* Gets implementation.
*
* @return the implementation
* @throws IOException
* the io exception
*/
public String getImplementation() throws IOException {
populate();
return implementation;
}
/**
* Gets required.
*
* @return the required
* @throws IOException
* the io exception
*/
public List<String> getRequired() throws IOException {
populate();
return required;
}
/**
* Gets permitted.
*
* @return the permitted
* @throws IOException
* the io exception
*/
public List<String> getPermitted() throws IOException {
populate();
return permitted;
}
/**
* Gets forbidden.
*
* @return the forbidden
* @throws IOException
* the io exception
*/
public List<String> getForbidden() throws IOException {
populate();
return forbidden;
}
/**
* Gets body.
*
* @return the body
* @throws IOException
* the io exception
*/
public String getBody() throws IOException {
populate();
return body;
@@ -138,19 +189,25 @@ public class GHLicense extends GHObject {
/**
* Fully populate the data by retrieving missing data.
*
* <p>
* Depending on the original API call where this object is created, it may not contain everything.
*
* @throws IOException
* the io exception
*/
protected synchronized void populate() throws IOException {
if (description!=null) return; // already populated
if (description != null)
return; // already populated
root.retrieve().withPreview(DRAX).to(url, this);
root.retrieve().to(url, this);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof GHLicense)) return false;
if (this == o)
return true;
if (!(o instanceof GHLicense))
return false;
GHLicense that = (GHLicense) o;
return this.url.equals(that.url);
@@ -161,7 +218,7 @@ public class GHLicense extends GHObject {
return url.hashCode();
}
/*package*/ GHLicense wrap(GitHub root) {
GHLicense wrap(GitHub root) {
this.root = root;
return this;
}

View File

@@ -8,7 +8,7 @@ import java.util.Locale;
* Represents a membership of a user in an organization.
*
* @author Kohsuke Kawaguchi
* @see GHMyself#listOrgMemberships()
* @see GHMyself#listOrgMemberships() GHMyself#listOrgMemberships()
*/
public class GHMembership /* extends GHObject --- but it doesn't have id, created_at, etc. */ {
GitHub root;
@@ -19,22 +19,47 @@ public class GHMembership /* extends GHObject --- but it doesn't have id, create
GHUser user;
GHOrganization organization;
/**
* Gets url.
*
* @return the url
*/
public URL getUrl() {
return GitHub.parseURL(url);
}
/**
* Gets state.
*
* @return the state
*/
public State getState() {
return Enum.valueOf(State.class, state.toUpperCase(Locale.ENGLISH));
}
/**
* Gets role.
*
* @return the role
*/
public Role getRole() {
return Enum.valueOf(Role.class, role.toUpperCase(Locale.ENGLISH));
}
/**
* Gets user.
*
* @return the user
*/
public GHUser getUser() {
return user;
}
/**
* Gets organization.
*
* @return the organization
*/
public GHOrganization getOrganization() {
return organization;
}
@@ -42,20 +67,24 @@ public class GHMembership /* extends GHObject --- but it doesn't have id, create
/**
* Accepts a pending invitation to an organization.
*
* @see GHMyself#getMembership(GHOrganization)
* @throws IOException
* the io exception
* @see GHMyself#getMembership(GHOrganization) GHMyself#getMembership(GHOrganization)
*/
public void activate() throws IOException {
root.retrieve().method("PATCH").with("state",State.ACTIVE).to(url,this);
root.retrieve().method("PATCH").with("state", State.ACTIVE).to(url, this);
}
/*package*/ GHMembership wrap(GitHub root) {
GHMembership wrap(GitHub root) {
this.root = root;
if (user!=null) user = root.getUser(user.wrapUp(root));
if (organization!=null) organization.wrapUp(root);
if (user != null)
user = root.getUser(user.wrapUp(root));
if (organization != null)
organization.wrapUp(root);
return this;
}
/*package*/ static void wrap(GHMembership[] page, GitHub root) {
static void wrap(GHMembership[] page, GitHub root) {
for (GHMembership m : page)
m.wrap(root);
}
@@ -78,7 +107,6 @@ public class GHMembership /* extends GHObject --- but it doesn't have id, create
* Whether a role is currently active or waiting for acceptance (pending)
*/
public enum State {
ACTIVE,
PENDING;
ACTIVE, PENDING;
}
}

View File

@@ -0,0 +1,89 @@
package org.kohsuke.github;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* Class that wraps the list of GitHub's IP addresses.
*
* @author Paulo Miguel Almeida
* @see GitHub#getMeta() GitHub#getMeta()
* @see <a href="https://developer.github.com/v3/meta/#meta">Get Meta</a>
*/
public class GHMeta {
@JsonProperty("verifiable_password_authentication")
private boolean verifiablePasswordAuthentication;
private List<String> hooks;
private List<String> git;
private List<String> web;
private List<String> api;
private List<String> pages;
private List<String> importer = new ArrayList<>();
/**
* Is verifiable password authentication boolean.
*
* @return the boolean
*/
public boolean isVerifiablePasswordAuthentication() {
return verifiablePasswordAuthentication;
}
/**
* Gets hooks.
*
* @return the hooks
*/
public List<String> getHooks() {
return Collections.unmodifiableList(hooks);
}
/**
* Gets git.
*
* @return the git
*/
public List<String> getGit() {
return Collections.unmodifiableList(git);
}
/**
* Gets web.
*
* @return the web
*/
public List<String> getWeb() {
return Collections.unmodifiableList(web);
}
/**
* Gets api.
*
* @return the api
*/
public List<String> getApi() {
return Collections.unmodifiableList(api);
}
/**
* Gets pages.
*
* @return the pages
*/
public List<String> getPages() {
return Collections.unmodifiableList(pages);
}
/**
* Gets importer.
*
* @return the importer
*/
public List<String> getImporter() {
return Collections.unmodifiableList(importer);
}
}

View File

@@ -6,9 +6,9 @@ import java.util.Date;
import java.util.Locale;
/**
*
* @author Yusuke Kokubo
* The type GHMilestone.
*
* @author Yusuke Kokubo
*/
public class GHMilestone extends GHObject {
GitHub root;
@@ -19,46 +19,98 @@ public class GHMilestone extends GHObject {
private int closed_issues, open_issues, number;
protected String closed_at;
/**
* Gets root.
*
* @return the root
*/
public GitHub getRoot() {
return root;
}
/**
* Gets owner.
*
* @return the owner
*/
public GHRepository getOwner() {
return owner;
}
/**
* Gets creator.
*
* @return the creator
* @throws IOException
* the io exception
*/
public GHUser getCreator() throws IOException {
return root.intern(creator);
}
/**
* Gets due on.
*
* @return the due on
*/
public Date getDueOn() {
if (due_on == null) return null;
if (due_on == null)
return null;
return GitHub.parseDate(due_on);
}
/**
* When was this milestone closed?
*
* @return the closed at
* @throws IOException
* the io exception
*/
public Date getClosedAt() throws IOException {
return GitHub.parseDate(closed_at);
}
/**
* Gets title.
*
* @return the title
*/
public String getTitle() {
return title;
}
/**
* Gets description.
*
* @return the description
*/
public String getDescription() {
return description;
}
/**
* Gets closed issues.
*
* @return the closed issues
*/
public int getClosedIssues() {
return closed_issues;
}
/**
* Gets open issues.
*
* @return the open issues
*/
public int getOpenIssues() {
return open_issues;
}
/**
* Gets number.
*
* @return the number
*/
public int getNumber() {
return number;
}
@@ -66,13 +118,21 @@ public class GHMilestone extends GHObject {
public URL getHtmlUrl() {
return GitHub.parseURL(html_url);
}
/**
* Gets state.
*
* @return the state
*/
public GHMilestoneState getState() {
return Enum.valueOf(GHMilestoneState.class, state.toUpperCase(Locale.ENGLISH));
}
/**
* Closes this milestone.
*
* @throws IOException
* the io exception
*/
public void close() throws IOException {
edit("state", "closed");
@@ -80,19 +140,80 @@ public class GHMilestone extends GHObject {
/**
* Reopens this milestone.
*
* @throws IOException
* the io exception
*/
public void reopen() throws IOException {
edit("state", "open");
}
/**
* Deletes this milestone.
*
* @throws IOException
* the io exception
*/
public void delete() throws IOException {
root.retrieve().method("DELETE").to(getApiRoute());
}
private void edit(String key, Object value) throws IOException {
new Requester(root)._with(key, value).method("PATCH").to(getApiRoute());
new Requester(root).with(key, value).method("PATCH").to(getApiRoute());
}
/**
* Sets title.
*
* @param title
* the title
* @throws IOException
* the io exception
*/
public void setTitle(String title) throws IOException {
edit("title", title);
}
/**
* Sets description.
*
* @param description
* the description
* @throws IOException
* the io exception
*/
public void setDescription(String description) throws IOException {
edit("description", description);
}
/**
* Sets due on.
*
* @param dueOn
* the due on
* @throws IOException
* the io exception
*/
public void setDueOn(Date dueOn) throws IOException {
edit("due_on", GitHub.printDate(dueOn));
}
/**
* Gets api route.
*
* @return the api route
*/
protected String getApiRoute() {
return "/repos/"+owner.getOwnerName()+"/"+owner.getName()+"/milestones/"+number;
return "/repos/" + owner.getOwnerName() + "/" + owner.getName() + "/milestones/" + number;
}
/**
* Wrap gh milestone.
*
* @param repo
* the repo
* @return the gh milestone
*/
public GHMilestone wrap(GHRepository repo) {
this.owner = repo;
this.root = repo.root;

View File

@@ -1,11 +1,10 @@
package org.kohsuke.github;
/**
*
* @author Yusuke Kokubo
* The enum GHMilestoneState.
*
* @author Yusuke Kokubo
*/
public enum GHMilestoneState {
OPEN,
CLOSED
OPEN, CLOSED
}

View File

@@ -44,8 +44,12 @@ public class GHMyself extends GHUser {
}
/**
* @deprecated
* Use {@link #getEmails2()}
* Gets emails.
*
* @return the emails
* @throws IOException
* the io exception
* @deprecated Use {@link #getEmails2()}
*/
public List<String> getEmails() throws IOException {
List<GHEmail> src = getEmails2();
@@ -58,13 +62,13 @@ public class GHMyself extends GHUser {
/**
* Returns the read-only list of e-mail addresses configured for you.
* <p>
* This corresponds to the stuff you configure in https://github.com/settings/emails, and not to be confused with
* {@link #getEmail()} that shows your public e-mail address set in https://github.com/settings/profile
*
* This corresponds to the stuff you configure in https://github.com/settings/emails,
* and not to be confused with {@link #getEmail()} that shows your public e-mail address
* set in https://github.com/settings/profile
*
* @return
* Always non-null.
* @return Always non-null.
* @throws IOException
* the io exception
*/
public List<GHEmail> getEmails2() throws IOException {
GHEmail[] addresses = root.retrieve().to("/user/emails", GHEmail[].class);
@@ -73,12 +77,13 @@ public class GHMyself extends GHUser {
/**
* Returns the read-only list of all the pulic keys of the current user.
* <p>
* NOTE: When using OAuth authenticaiton, the READ/WRITE User scope is required by the GitHub APIs, otherwise you
* will get a 404 NOT FOUND.
*
* NOTE: When using OAuth authenticaiton, the READ/WRITE User scope is
* required by the GitHub APIs, otherwise you will get a 404 NOT FOUND.
*
* @return
* Always non-null.
* @return Always non-null.
* @throws IOException
* the io exception
*/
public List<GHKey> getPublicKeys() throws IOException {
return Collections.unmodifiableList(Arrays.asList(root.retrieve().to("/user/keys", GHKey[].class)));
@@ -86,27 +91,31 @@ public class GHMyself extends GHUser {
/**
* Returns the read-only list of all the public verified keys of the current user.
* <p>
* Differently from the getPublicKeys() method, the retrieval of the user's verified public keys does not require
* any READ/WRITE OAuth Scope to the user's profile.
*
* Differently from the getPublicKeys() method, the retrieval of the user's
* verified public keys does not require any READ/WRITE OAuth Scope to the
* user's profile.
*
* @return
* Always non-null.
* @return Always non-null.
* @throws IOException
* the io exception
*/
public List<GHVerifiedKey> getPublicVerifiedKeys() throws IOException {
return Collections.unmodifiableList(Arrays.asList(root.retrieve().to(
"/users/" + getLogin() + "/keys", GHVerifiedKey[].class)));
}
public List<GHVerifiedKey> getPublicVerifiedKeys() throws IOException {
return Collections.unmodifiableList(
Arrays.asList(root.retrieve().to("/users/" + getLogin() + "/keys", GHVerifiedKey[].class)));
}
/**
* Gets the organization that this user belongs to.
*
* @return the all organizations
* @throws IOException
* the io exception
*/
public GHPersonSet<GHOrganization> getAllOrganizations() throws IOException {
GHPersonSet<GHOrganization> orgs = new GHPersonSet<GHOrganization>();
Set<String> names = new HashSet<String>();
for (GHOrganization o : root.retrieve().to("/user/orgs", GHOrganization[].class)) {
if (names.add(o.getLogin())) // in case of rumoured duplicates in the data
if (names.add(o.getLogin())) // in case of rumoured duplicates in the data
orgs.add(root.getOrganization(o.getLogin()));
}
return orgs;
@@ -114,11 +123,15 @@ public class GHMyself extends GHUser {
/**
* Gets the all repositories this user owns (public and private).
*
* @return the all repositories
* @throws IOException
* the io exception
*/
public synchronized Map<String,GHRepository> getAllRepositories() throws IOException {
Map<String,GHRepository> repositories = new TreeMap<String, GHRepository>();
public synchronized Map<String, GHRepository> getAllRepositories() throws IOException {
Map<String, GHRepository> repositories = new TreeMap<String, GHRepository>();
for (GHRepository r : listAllRepositories()) {
repositories.put(r.getName(),r);
repositories.put(r.getName(), r);
}
return Collections.unmodifiableMap(repositories);
}
@@ -126,52 +139,53 @@ public class GHMyself extends GHUser {
/**
* Lists up all repositories this user owns (public and private).
*
* Unlike {@link #getAllRepositories()}, this does not wait until all the repositories are returned.
* Repositories are returned by GitHub API with a 30 items per page.
* Unlike {@link #getAllRepositories()}, this does not wait until all the repositories are returned. Repositories
* are returned by GitHub API with a 30 items per page.
*/
@Override
public PagedIterable<GHRepository> listRepositories() {
return listRepositories(30);
return listRepositories(30);
}
/**
* List repositories that are accessible to the authenticated user (public and private) using the specified page size.
* List repositories that are accessible to the authenticated user (public and private) using the specified page
* size.
*
* This includes repositories owned by the authenticated user, repositories that belong to other users
* where the authenticated user is a collaborator, and other organizations' repositories that the authenticated
* user has access to through an organization membership.
* This includes repositories owned by the authenticated user, repositories that belong to other users where the
* authenticated user is a collaborator, and other organizations' repositories that the authenticated user has
* access to through an organization membership.
*
* @param pageSize size for each page of items returned by GitHub. Maximum page size is 100.
* @param pageSize
* size for each page of items returned by GitHub. Maximum page size is 100.
*
* Unlike {@link #getRepositories()}, this does not wait until all the repositories are returned.
* Unlike {@link #getRepositories()}, this does not wait until all the repositories are returned.
*/
public PagedIterable<GHRepository> listRepositories(final int pageSize) {
return listRepositories(pageSize, RepositoryListFilter.ALL);
}
/**
* List repositories of a certain type that are accessible by current authenticated user using the specified page size.
* List repositories of a certain type that are accessible by current authenticated user using the specified page
* size.
*
* @param pageSize size for each page of items returned by GitHub. Maximum page size is 100.
* @param repoType type of repository returned in the listing
* @param pageSize
* size for each page of items returned by GitHub. Maximum page size is 100.
* @param repoType
* type of repository returned in the listing
* @return the paged iterable
*/
public PagedIterable<GHRepository> listRepositories(final int pageSize, final RepositoryListFilter repoType) {
return new PagedIterable<GHRepository>() {
public PagedIterator<GHRepository> _iterator(int pageSize) {
return new PagedIterator<GHRepository>(root.retrieve().with("type",repoType).asIterator("/user/repos", GHRepository[].class, pageSize)) {
@Override
protected void wrapUp(GHRepository[] page) {
for (GHRepository c : page)
c.wrap(root);
}
};
}
}.withPageSize(pageSize);
return root.retrieve()
.with("type", repoType)
.asPagedIterable("/user/repos", GHRepository[].class, item -> item.wrap(root))
.withPageSize(pageSize);
}
/**
* @deprecated
* Use {@link #listRepositories()}
* List all repositories paged iterable.
*
* @return the paged iterable
* @deprecated Use {@link #listRepositories()}
*/
public PagedIterable<GHRepository> listAllRepositories() {
return listRepositories();
@@ -179,6 +193,8 @@ public class GHMyself extends GHUser {
/**
* List your organization memberships
*
* @return the paged iterable
*/
public PagedIterable<GHMembership> listOrgMemberships() {
return listOrgMemberships(null);
@@ -188,30 +204,30 @@ public class GHMyself extends GHUser {
* List your organization memberships
*
* @param state
* Filter by a specific state
* Filter by a specific state
* @return the paged iterable
*/
public PagedIterable<GHMembership> listOrgMemberships(final GHMembership.State state) {
return new PagedIterable<GHMembership>() {
public PagedIterator<GHMembership> _iterator(int pageSize) {
return new PagedIterator<GHMembership>(root.retrieve().with("state",state).asIterator("/user/memberships/orgs", GHMembership[].class, pageSize)) {
@Override
protected void wrapUp(GHMembership[] page) {
GHMembership.wrap(page,root);
}
};
}
};
return root.retrieve()
.with("state", state)
.asPagedIterable("/user/memberships/orgs", GHMembership[].class, item -> item.wrap(root));
}
/**
* Gets your membership in a specific organization.
*
* @param o
* the o
* @return the membership
* @throws IOException
* the io exception
*/
public GHMembership getMembership(GHOrganization o) throws IOException {
return root.retrieve().to("/user/memberships/orgs/"+o.getLogin(),GHMembership.class).wrap(root);
return root.retrieve().to("/user/memberships/orgs/" + o.getLogin(), GHMembership.class).wrap(root);
}
// public void addEmails(Collection<String> emails) throws IOException {
//// new Requester(root,ApiVersion.V3).withCredential().to("/user/emails");
// root.retrieveWithAuth3()
// }
// public void addEmails(Collection<String> emails) throws IOException {
//// new Requester(root,ApiVersion.V3).withCredential().to("/user/emails");
// root.retrieveWithAuth3()
// }
}

View File

@@ -9,23 +9,19 @@ import java.util.NoSuchElementException;
* Listens to GitHub notification stream.
*
* <p>
* This class supports two modes of retrieving notifications that can
* be controlled via {@link #nonBlocking(boolean)}.
* This class supports two modes of retrieving notifications that can be controlled via {@link #nonBlocking(boolean)}.
*
* <p>
* In the blocking mode, which is the default, iterator will be infinite.
* The call to {@link Iterator#next()} will block until a new notification
* arrives. This is useful for application that runs perpetually and reacts
* to notifications.
* In the blocking mode, which is the default, iterator will be infinite. The call to {@link Iterator#next()} will block
* until a new notification arrives. This is useful for application that runs perpetually and reacts to notifications.
*
* <p>
* In the non-blocking mode, the iterator will only report the set of
* notifications initially retrieved from GitHub, then quit. This is useful
* for a batch application to process the current set of notifications.
* In the non-blocking mode, the iterator will only report the set of notifications initially retrieved from GitHub,
* then quit. This is useful for a batch application to process the current set of notifications.
*
* @author Kohsuke Kawaguchi
* @see GitHub#listNotifications()
* @see GHRepository#listNotifications()
* @see GitHub#listNotifications() GitHub#listNotifications()
* @see GHRepository#listNotifications() GHRepository#listNotifications()
*/
public class GHNotificationStream implements Iterable<GHThread> {
private final GitHub root;
@@ -35,13 +31,17 @@ public class GHNotificationStream implements Iterable<GHThread> {
private String apiUrl;
private boolean nonBlocking = false;
/*package*/ GHNotificationStream(GitHub root, String apiUrl) {
GHNotificationStream(GitHub root, String apiUrl) {
this.root = root;
this.apiUrl = apiUrl;
}
/**
* Should the stream include notifications that are already read?
*
* @param v
* the v
* @return the gh notification stream
*/
public GHNotificationStream read(boolean v) {
all = v;
@@ -49,26 +49,47 @@ public class GHNotificationStream implements Iterable<GHThread> {
}
/**
* Should the stream be restricted to notifications in which the user
* is directly participating or mentioned?
* Should the stream be restricted to notifications in which the user is directly participating or mentioned?
*
* @param v
* the v
* @return the gh notification stream
*/
public GHNotificationStream participating(boolean v) {
participating = v;
return this;
}
/**
* Since gh notification stream.
*
* @param timestamp
* the timestamp
* @return the gh notification stream
*/
public GHNotificationStream since(long timestamp) {
return since(new Date(timestamp));
}
/**
* Since gh notification stream.
*
* @param dt
* the dt
* @return the gh notification stream
*/
public GHNotificationStream since(Date dt) {
since = GitHub.printDate(dt);
return this;
}
/**
* If set to true, {@link #iterator()} will stop iterating instead of blocking and
* waiting for the updates to arrive.
* If set to true, {@link #iterator()} will stop iterating instead of blocking and waiting for the updates to
* arrive.
*
* @param v
* the v
* @return the gh notification stream
*/
public GHNotificationStream nonBlocking(boolean v) {
this.nonBlocking = v;
@@ -76,25 +97,25 @@ public class GHNotificationStream implements Iterable<GHThread> {
}
/**
* Returns an infinite blocking {@link Iterator} that returns
* {@link GHThread} as notifications arrive.
* Returns an infinite blocking {@link Iterator} that returns {@link GHThread} as notifications arrive.
*/
public Iterator<GHThread> iterator() {
// capture the configuration setting here
final Requester req = new Requester(root).method("GET")
.with("all", all).with("participating", participating).with("since", since);
.with("all", all)
.with("participating", participating)
.with("since", since);
return new Iterator<GHThread>() {
/**
* Stuff we've fetched but haven't returned to the caller.
* Newer ones first.
* Stuff we've fetched but haven't returned to the caller. Newer ones first.
*/
private GHThread[] threads = EMPTY_ARRAY;
/**
* Next element in {@link #threads} to return. This counts down.
*/
private int idx=-1;
private int idx = -1;
/**
* threads whose updated_at is older than this should be ignored.
@@ -114,9 +135,9 @@ public class GHNotificationStream implements Iterable<GHThread> {
private GHThread next;
public GHThread next() {
if (next==null) {
if (next == null) {
next = fetch();
if (next==null)
if (next == null)
throw new NoSuchElementException();
}
@@ -126,9 +147,9 @@ public class GHNotificationStream implements Iterable<GHThread> {
}
public boolean hasNext() {
if (next==null)
if (next == null)
next = fetch();
return next!=null;
return next != null;
}
GHThread fetch() {
@@ -136,7 +157,7 @@ public class GHNotificationStream implements Iterable<GHThread> {
while (true) {// loop until we get new threads to return
// if we have fetched un-returned threads, use them first
while (idx>=0) {
while (idx >= 0) {
GHThread n = threads[idx--];
long nt = n.getUpdatedAt().getTime();
if (nt >= lastUpdated) {
@@ -145,13 +166,14 @@ public class GHNotificationStream implements Iterable<GHThread> {
}
}
if (nonBlocking && nextCheckTime>=0)
return null; // nothing more to report, and we aren't blocking
if (nonBlocking && nextCheckTime >= 0)
return null; // nothing more to report, and we aren't blocking
// observe the polling interval before making the call
while (true) {
long now = System.currentTimeMillis();
if (nextCheckTime < now) break;
if (nextCheckTime < now)
break;
long waitTime = Math.min(Math.max(nextCheckTime - now, 1000), 60 * 1000);
Thread.sleep(waitTime);
}
@@ -159,13 +181,13 @@ public class GHNotificationStream implements Iterable<GHThread> {
req.setHeader("If-Modified-Since", lastModified);
threads = req.to(apiUrl, GHThread[].class);
if (threads==null) {
threads = EMPTY_ARRAY; // if unmodified, we get empty array
if (threads == null) {
threads = EMPTY_ARRAY; // if unmodified, we get empty array
} else {
// we get a new batch, but we want to ignore the ones that we've seen
lastUpdated++;
}
idx = threads.length-1;
idx = threads.length - 1;
nextCheckTime = calcNextCheckTime();
lastModified = req.getResponseHeader("Last-Modified");
@@ -179,9 +201,10 @@ public class GHNotificationStream implements Iterable<GHThread> {
private long calcNextCheckTime() {
String v = req.getResponseHeader("X-Poll-Interval");
if (v==null) v="60";
if (v == null)
v = "60";
long seconds = Integer.parseInt(v);
return System.currentTimeMillis() + seconds*1000;
return System.currentTimeMillis() + seconds * 1000;
}
public void remove() {
@@ -190,16 +213,27 @@ public class GHNotificationStream implements Iterable<GHThread> {
};
}
/**
* Mark as read.
*
* @throws IOException
* the io exception
*/
public void markAsRead() throws IOException {
markAsRead(-1);
}
/**
* Marks all the notifications as read.
*
* @param timestamp
* the timestamp
* @throws IOException
* the io exception
*/
public void markAsRead(long timestamp) throws IOException {
final Requester req = new Requester(root).method("PUT");
if (timestamp>=0)
if (timestamp >= 0)
req.with("last_read_at", GitHub.printDate(new Date(timestamp)));
req.asHttpStatusCode(apiUrl);
}

View File

@@ -0,0 +1,10 @@
package org.kohsuke.github;
/**
* This exception is thrown when GitHub is requesting an OTP from the user
*
* @author Kevin Harrington mad.hephaestus@gmail.com
*/
public class GHOTPRequiredException extends GHIOException {
// ...
}

View File

@@ -2,10 +2,9 @@ package org.kohsuke.github;
import com.infradna.tool.bridge_method_injector.WithBridgeMethods;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import org.apache.commons.lang.builder.ReflectionToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import javax.annotation.CheckForNull;
import java.io.IOException;
import java.lang.reflect.Field;
import java.net.URL;
@@ -13,11 +12,13 @@ import java.util.Date;
import java.util.List;
import java.util.Map;
import javax.annotation.CheckForNull;
/**
* Most (all?) domain objects in GitHub seems to have these 4 properties.
*/
@SuppressFBWarnings(value = {"UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD",
"NP_UNWRITTEN_FIELD"}, justification = "JSON API")
@SuppressFBWarnings(value = { "UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD", "NP_UNWRITTEN_FIELD" },
justification = "JSON API")
public abstract class GHObject {
/**
* Capture response HTTP headers on the state object.
@@ -29,28 +30,35 @@ public abstract class GHObject {
protected String created_at;
protected String updated_at;
/*package*/ GHObject() {
GHObject() {
}
/**
* Returns the HTTP response headers given along with the state of this object.
*
* <p>
* Some of the HTTP headers have nothing to do with the object, for example "Cache-Control"
* and others are different depending on how this object was retrieved.
* Some of the HTTP headers have nothing to do with the object, for example "Cache-Control" and others are different
* depending on how this object was retrieved.
* <p>
* This method was added as a kind of hack to allow the caller to retrieve OAuth scopes and such. Use with caution.
* The method might be removed in the future.
*
* This method was added as a kind of hack to allow the caller to retrieve OAuth scopes and such.
* Use with caution. The method might be removed in the future.
* @return a map of header names to value lists
*/
@CheckForNull @Deprecated
@CheckForNull
@Deprecated
public Map<String, List<String>> getResponseHeaderFields() {
return responseHeaderFields;
}
/**
* When was this resource created?
*
* @return date created
* @throws IOException
* on error
*/
@WithBridgeMethods(value=String.class, adapterMethod="createdAtStr")
@WithBridgeMethods(value = String.class, adapterMethod = "createdAtStr")
public Date getCreatedAt() throws IOException {
return GitHub.parseDate(created_at);
}
@@ -61,51 +69,63 @@ public abstract class GHObject {
}
/**
* API URL of this object.
* Gets url.
*
* @return API URL of this object.
*/
@WithBridgeMethods(value=String.class, adapterMethod="urlToString")
@WithBridgeMethods(value = String.class, adapterMethod = "urlToString")
public URL getUrl() {
return GitHub.parseURL(url);
}
/**
* URL of this object for humans, which renders some HTML.
* Gets html url.
*
* @return URL of this object for humans, which renders some HTML.
* @throws IOException
* on error
*/
@WithBridgeMethods(value=String.class, adapterMethod="urlToString")
@WithBridgeMethods(value = String.class, adapterMethod = "urlToString")
public abstract URL getHtmlUrl() throws IOException;
/**
* When was this resource last updated?
*
* @return updated date
* @throws IOException
* on error
*/
public Date getUpdatedAt() throws IOException {
return GitHub.parseDate(updated_at);
}
/**
* Unique ID number of this resource.
* Gets id.
*
* @return Unique ID number of this resource.
*/
@WithBridgeMethods(value={String.class,int.class}, adapterMethod="longToStringOrInt")
@WithBridgeMethods(value = { String.class, int.class }, adapterMethod = "longToStringOrInt")
public long getId() {
return id;
}
@SuppressFBWarnings(value = "UPM_UNCALLED_PRIVATE_METHOD", justification = "Bridge method of getId")
private Object longToStringOrInt(long id, Class type) {
if (type==String.class)
if (type == String.class)
return String.valueOf(id);
if (type==int.class)
return (int)id;
throw new AssertionError("Unexpected type: "+type);
if (type == int.class)
return (int) id;
throw new AssertionError("Unexpected type: " + type);
}
@SuppressFBWarnings(value = "UPM_UNCALLED_PRIVATE_METHOD", justification = "Bridge method of getHtmlUrl")
private Object urlToString(URL url, Class type) {
return url==null ? null : url.toString();
return url == null ? null : url.toString();
}
/**
* String representation to assist debugging and inspection. The output format of this string
* is not a committed part of the API and is subject to change.
* String representation to assist debugging and inspection. The output format of this string is not a committed
* part of the API and is subject to change.
*/
@Override
public String toString() {
@@ -134,7 +154,7 @@ public abstract class GHObject {
if (value instanceof GitHub)
return;
super.append(buffer,fieldName,value,fullDetail);
super.append(buffer, fieldName, value, fullDetail);
}
};
}

View File

@@ -8,9 +8,9 @@ class GHOrgHook extends GHHook {
/**
* Organization that the hook belongs to.
*/
/*package*/ transient GHOrganization organization;
transient GHOrganization organization;
/*package*/ GHOrgHook wrap(GHOrganization owner) {
GHOrgHook wrap(GHOrganization owner) {
this.organization = owner;
return this;
}

View File

@@ -10,84 +10,135 @@ import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import static org.kohsuke.github.Previews.INERTIA;
/**
* The type GHOrganization.
*
* @author Kohsuke Kawaguchi
*/
public class GHOrganization extends GHPerson {
/*package*/ GHOrganization wrapUp(GitHub root) {
return (GHOrganization)super.wrapUp(root);
GHOrganization wrapUp(GitHub root) {
return (GHOrganization) super.wrapUp(root);
}
/**
* Creates a new repository.
*
* @return
* Newly created repository.
* @deprecated
* Use {@link #createRepository(String)} that uses a builder pattern to let you control every aspect.
* @param name
* the name
* @param description
* the description
* @param homepage
* the homepage
* @param team
* the team
* @param isPublic
* the is public
* @return Newly created repository.
* @throws IOException
* the io exception
* @deprecated Use {@link #createRepository(String)} that uses a builder pattern to let you control every aspect.
*/
public GHRepository createRepository(String name, String description, String homepage, String team, boolean isPublic) throws IOException {
public GHRepository createRepository(String name,
String description,
String homepage,
String team,
boolean isPublic) throws IOException {
GHTeam t = getTeams().get(team);
if (t==null)
throw new IllegalArgumentException("No such team: "+team);
if (t == null)
throw new IllegalArgumentException("No such team: " + team);
return createRepository(name, description, homepage, t, isPublic);
}
/**
* @deprecated
* Use {@link #createRepository(String)} that uses a builder pattern to let you control every aspect.
* Create repository gh repository.
*
* @param name
* the name
* @param description
* the description
* @param homepage
* the homepage
* @param team
* the team
* @param isPublic
* the is public
* @return the gh repository
* @throws IOException
* the io exception
* @deprecated Use {@link #createRepository(String)} that uses a builder pattern to let you control every aspect.
*/
public GHRepository createRepository(String name, String description, String homepage, GHTeam team, boolean isPublic) throws IOException {
if (team==null)
public GHRepository createRepository(String name,
String description,
String homepage,
GHTeam team,
boolean isPublic) throws IOException {
if (team == null)
throw new IllegalArgumentException("Invalid team");
return createRepository(name).description(description).homepage(homepage).private_(!isPublic).team(team).create();
return createRepository(name).description(description)
.homepage(homepage)
.private_(!isPublic)
.team(team)
.create();
}
/**
* Starts a builder that creates a new repository.
*
* <p>
* You use the returned builder to set various properties, then call {@link GHCreateRepositoryBuilder#create()}
* to finally createa repository.
* You use the returned builder to set various properties, then call {@link GHCreateRepositoryBuilder#create()} to
* finally createa repository.
*
* @param name
* the name
* @return the gh create repository builder
*/
public GHCreateRepositoryBuilder createRepository(String name) throws IOException {
return new GHCreateRepositoryBuilder(root,"/orgs/"+login+"/repos",name);
public GHCreateRepositoryBuilder createRepository(String name) {
return new GHCreateRepositoryBuilder(root, "/orgs/" + login + "/repos", name);
}
/**
* Teams by their names.
*
* @return the teams
* @throws IOException
* the io exception
*/
public Map<String,GHTeam> getTeams() throws IOException {
Map<String,GHTeam> r = new TreeMap<String, GHTeam>();
public Map<String, GHTeam> getTeams() throws IOException {
Map<String, GHTeam> r = new TreeMap<String, GHTeam>();
for (GHTeam t : listTeams()) {
r.put(t.getName(),t);
r.put(t.getName(), t);
}
return r;
}
/**
* List up all the teams.
*
* @return the paged iterable
* @throws IOException
* the io exception
*/
public PagedIterable<GHTeam> listTeams() throws IOException {
return new PagedIterable<GHTeam>() {
public PagedIterator<GHTeam> _iterator(int pageSize) {
return new PagedIterator<GHTeam>(root.retrieve().asIterator(String.format("/orgs/%s/teams", login), GHTeam[].class, pageSize)) {
@Override
protected void wrapUp(GHTeam[] page) {
for (GHTeam c : page)
c.wrapUp(GHOrganization.this);
}
};
}
};
return root.retrieve()
.asPagedIterable(String.format("/orgs/%s/teams", login),
GHTeam[].class,
item -> item.wrapUp(GHOrganization.this));
}
/**
* Finds a team that has the given name in its {@link GHTeam#getName()}
*
* @param name
* the name
* @return the team by name
* @throws IOException
* the io exception
*/
public GHTeam getTeamByName(String name) throws IOException {
for (GHTeam t : listTeams()) {
if(t.getName().equals(name))
if (t.getName().equals(name))
return t;
}
return null;
@@ -95,21 +146,59 @@ public class GHOrganization extends GHPerson {
/**
* Finds a team that has the given slug in its {@link GHTeam#getSlug()}
*
* @param slug
* the slug
* @return the team by slug
* @throws IOException
* the io exception
*/
public GHTeam getTeamBySlug(String slug) throws IOException {
for (GHTeam t : listTeams()) {
if(t.getSlug().equals(slug))
if (t.getSlug().equals(slug))
return t;
}
return null;
}
/**
* Member's role in an organization
*/
public enum Role {
ADMIN,
/** The user is an owner of the organization. */
MEMBER /** The user is a non-owner member of the organization. */
}
/**
* Adds (invites) a user to the organization.
*
* @param user
* the user
* @param role
* the role
* @throws IOException
* the io exception
* @see <a href=
* "https://developer.github.com/v3/orgs/members/#add-or-update-organization-membership">documentation</a>
*/
public void add(GHUser user, Role role) throws IOException {
root.retrieve()
.method("PUT")
.with("role", role.name().toLowerCase())
.to("/orgs/" + login + "/memberships/" + user.getLogin());
}
/**
* Checks if this organization has the specified user as a member.
*
* @param user
* the user
* @return the boolean
*/
public boolean hasMember(GHUser user) {
try {
root.retrieve().to("/orgs/" + login + "/members/" + user.getLogin());
root.retrieve().to("/orgs/" + login + "/members/" + user.getLogin());
return true;
} catch (IOException ignore) {
return false;
@@ -117,15 +206,24 @@ public class GHOrganization extends GHPerson {
}
/**
* Remove a member of the organisation - which will remove them from
* all teams, and remove their access to the organizations repositories.
* Remove a member of the organisation - which will remove them from all teams, and remove their access to the
* organizations repositories.
*
* @param user
* the user
* @throws IOException
* the io exception
*/
public void remove(GHUser user) throws IOException {
root.retrieve().method("DELETE").to("/orgs/" + login + "/members/" + user.getLogin());
root.retrieve().method("DELETE").to("/orgs/" + login + "/members/" + user.getLogin());
}
/**
* Checks if this organization has the specified user as a public member.
*
* @param user
* the user
* @return the boolean
*/
public boolean hasPublicMember(GHUser user) {
try {
@@ -138,12 +236,22 @@ public class GHOrganization extends GHPerson {
/**
* Publicizes the membership.
*
* @param u
* the u
* @throws IOException
* the io exception
*/
public void publicize(GHUser u) throws IOException {
root.retrieve().method("PUT").to("/orgs/" + login + "/public_members/" + u.getLogin(), null);
}
/**
* Gets members.
*
* @return the members
* @throws IOException
* the io exception
* @deprecated use {@link #listMembers()}
*/
public List<GHUser> getMembers() throws IOException {
@@ -152,6 +260,10 @@ public class GHOrganization extends GHPerson {
/**
* All the members of this organization.
*
* @return the paged iterable
* @throws IOException
* the io exception
*/
public PagedIterable<GHUser> listMembers() throws IOException {
return listMembers("members");
@@ -159,6 +271,10 @@ public class GHOrganization extends GHPerson {
/**
* All the public members of this organization.
*
* @return the paged iterable
* @throws IOException
* the io exception
*/
public PagedIterable<GHUser> listPublicMembers() throws IOException {
return listMembers("public_members");
@@ -168,55 +284,185 @@ public class GHOrganization extends GHPerson {
return listMembers(suffix, null);
}
/**
* List members with filter paged iterable.
*
* @param filter
* the filter
* @return the paged iterable
* @throws IOException
* the io exception
*/
public PagedIterable<GHUser> listMembersWithFilter(String filter) throws IOException {
return listMembers("members", filter);
}
private PagedIterable<GHUser> listMembers(final String suffix, final String filter) throws IOException {
return new PagedIterable<GHUser>() {
public PagedIterator<GHUser> _iterator(int pageSize) {
String filterParams = (filter == null) ? "" : ("?filter=" + filter);
return new PagedIterator<GHUser>(root.retrieve().asIterator(String.format("/orgs/%s/%s%s", login, suffix, filterParams), GHUser[].class, pageSize)) {
@Override
protected void wrapUp(GHUser[] users) {
GHUser.wrap(users, root);
}
};
}
};
String filterParams = (filter == null) ? "" : ("?filter=" + filter);
return root.retrieve()
.asPagedIterable(String.format("/orgs/%s/%s%s", login, suffix, filterParams),
GHUser[].class,
item -> item.wrapUp(root));
}
/**
* Conceals the membership.
*
* @param u
* the u
* @throws IOException
* the io exception
*/
public void conceal(GHUser u) throws IOException {
root.retrieve().method("DELETE").to("/orgs/" + login + "/public_members/" + u.getLogin(), null);
}
public enum Permission { ADMIN, PUSH, PULL }
/**
* Returns the projects for this organization.
*
* @param status
* The status filter (all, open or closed).
* @return the paged iterable
* @throws IOException
* the io exception
*/
public PagedIterable<GHProject> listProjects(final GHProject.ProjectStateFilter status) throws IOException {
return root.retrieve()
.withPreview(INERTIA)
.with("state", status)
.asPagedIterable(String.format("/orgs/%s/projects", login), GHProject[].class, item -> item.wrap(root));
}
/**
* Returns all open projects for the organization.
*
* @return the paged iterable
* @throws IOException
* the io exception
*/
public PagedIterable<GHProject> listProjects() throws IOException {
return listProjects(GHProject.ProjectStateFilter.OPEN);
}
/**
* Creates a project for the organization.
*
* @param name
* the name
* @param body
* the body
* @return the gh project
* @throws IOException
* the io exception
*/
public GHProject createProject(String name, String body) throws IOException {
return root.retrieve()
.method("POST")
.withPreview(INERTIA)
.with("name", name)
.with("body", body)
.to(String.format("/orgs/%s/projects", login), GHProject.class)
.wrap(root);
}
/**
* The enum Permission.
*/
public enum Permission {
ADMIN, PUSH, PULL
}
/**
* Creates a new team and assigns the repositories.
*
* @param name
* the name
* @param p
* the p
* @param repositories
* the repositories
* @return the gh team
* @throws IOException
* the io exception
* @deprecated https://developer.github.com/v3/teams/#create-team deprecates permission field use
* {@link #createTeam(String, Collection)}
*/
@Deprecated
public GHTeam createTeam(String name, Permission p, Collection<GHRepository> repositories) throws IOException {
Requester post = new Requester(root).with("name", name).with("permission", p);
List<String> repo_names = new ArrayList<String>();
for (GHRepository r : repositories) {
repo_names.add(r.getName());
repo_names.add(login + "/" + r.getName());
}
post.with("repo_names",repo_names);
post.with("repo_names", repo_names);
return post.method("POST").to("/orgs/" + login + "/teams", GHTeam.class).wrapUp(this);
}
/**
* Create team gh team.
*
* @param name
* the name
* @param p
* the p
* @param repositories
* the repositories
* @return the gh team
* @throws IOException
* the io exception
* @deprecated https://developer.github.com/v3/teams/#create-team deprecates permission field use
* {@link #createTeam(String, GHRepository...)}
*/
@Deprecated
public GHTeam createTeam(String name, Permission p, GHRepository... repositories) throws IOException {
return createTeam(name, p, Arrays.asList(repositories));
}
/**
* List up repositories that has some open pull requests.
* Creates a new team and assigns the repositories.
*
* This used to be an efficient method that didn't involve traversing every repository, but now
* it doesn't do any optimization.
* @param name
* the name
* @param repositories
* the repositories
* @return the gh team
* @throws IOException
* the io exception
*/
public GHTeam createTeam(String name, Collection<GHRepository> repositories) throws IOException {
Requester post = new Requester(root).with("name", name);
List<String> repo_names = new ArrayList<String>();
for (GHRepository r : repositories) {
repo_names.add(login + "/" + r.getName());
}
post.with("repo_names", repo_names);
return post.method("POST").to("/orgs/" + login + "/teams", GHTeam.class).wrapUp(this);
}
/**
* Create team gh team.
*
* @param name
* the name
* @param repositories
* the repositories
* @return the gh team
* @throws IOException
* the io exception
*/
public GHTeam createTeam(String name, GHRepository... repositories) throws IOException {
return createTeam(name, Arrays.asList(repositories));
}
/**
* List up repositories that has some open pull requests.
* <p>
* This used to be an efficient method that didn't involve traversing every repository, but now it doesn't do any
* optimization.
*
* @return the repositories with open pull requests
* @throws IOException
* the io exception
*/
public List<GHRepository> getRepositoriesWithOpenPullRequests() throws IOException {
List<GHRepository> r = new ArrayList<GHRepository>();
@@ -232,6 +478,10 @@ public class GHOrganization extends GHPerson {
/**
* Gets all the open pull requests in this organizataion.
*
* @return the pull requests
* @throws IOException
* the io exception
*/
public List<GHPullRequest> getPullRequests() throws IOException {
List<GHPullRequest> all = new ArrayList<GHPullRequest>();
@@ -245,72 +495,96 @@ public class GHOrganization extends GHPerson {
* Lists events performed by a user (this includes private events if the caller is authenticated.
*/
public PagedIterable<GHEventInfo> listEvents() throws IOException {
return new PagedIterable<GHEventInfo>() {
public PagedIterator<GHEventInfo> _iterator(int pageSize) {
return new PagedIterator<GHEventInfo>(root.retrieve().asIterator(String.format("/orgs/%s/events", login), GHEventInfo[].class, pageSize)) {
@Override
protected void wrapUp(GHEventInfo[] page) {
for (GHEventInfo c : page)
c.wrapUp(root);
}
};
}
};
return root.retrieve()
.asPagedIterable(String.format("/orgs/%s/events", login),
GHEventInfo[].class,
item -> item.wrapUp(root));
}
/**
* Lists up all the repositories using the specified page size.
*
* @param pageSize size for each page of items returned by GitHub. Maximum page size is 100.
* @param pageSize
* size for each page of items returned by GitHub. Maximum page size is 100.
*
* Unlike {@link #getRepositories()}, this does not wait until all the repositories are returned.
* Unlike {@link #getRepositories()}, this does not wait until all the repositories are returned.
*/
@Override
public PagedIterable<GHRepository> listRepositories(final int pageSize) {
return new PagedIterable<GHRepository>() {
public PagedIterator<GHRepository> _iterator(int pageSize) {
return new PagedIterator<GHRepository>(root.retrieve().asIterator("/orgs/" + login + "/repos?per_page=" + pageSize, GHRepository[].class, pageSize)) {
@Override
protected void wrapUp(GHRepository[] page) {
for (GHRepository c : page)
c.wrap(root);
}
};
}
};
return root.retrieve()
.asPagedIterable("/orgs/" + login + "/repos", GHRepository[].class, item -> item.wrap(root))
.withPageSize(pageSize);
}
/**
* Retrieves the currently configured hooks.
*
* @return the hooks
* @throws IOException
* the io exception
*/
public List<GHHook> getHooks() throws IOException {
return GHHooks.orgContext(this).getHooks();
}
/**
* Gets hook.
*
* @param id
* the id
* @return the hook
* @throws IOException
* the io exception
*/
public GHHook getHook(int id) throws IOException {
return GHHooks.orgContext(this).getHook(id);
}
/**
*
* See https://api.github.com/hooks for possible names and their configuration scheme.
* TODO: produce type-safe binding
* See https://api.github.com/hooks for possible names and their configuration scheme. TODO: produce type-safe
* binding
*
* @param name
* Type of the hook to be created. See https://api.github.com/hooks for possible names.
* Type of the hook to be created. See https://api.github.com/hooks for possible names.
* @param config
* The configuration hash.
* The configuration hash.
* @param events
* Can be null. Types of events to hook into.
* Can be null. Types of events to hook into.
* @param active
* the active
* @return the gh hook
* @throws IOException
* the io exception
*/
public GHHook createHook(String name, Map<String,String> config, Collection<GHEvent> events, boolean active) throws IOException {
public GHHook createHook(String name, Map<String, String> config, Collection<GHEvent> events, boolean active)
throws IOException {
return GHHooks.orgContext(this).createHook(name, config, events, active);
}
/**
* Create web hook gh hook.
*
* @param url
* the url
* @param events
* the events
* @return the gh hook
* @throws IOException
* the io exception
*/
public GHHook createWebHook(URL url, Collection<GHEvent> events) throws IOException {
return createHook("web", Collections.singletonMap("url", url.toExternalForm()),events,true);
return createHook("web", Collections.singletonMap("url", url.toExternalForm()), events, true);
}
/**
* Create web hook gh hook.
*
* @param url
* the url
* @return the gh hook
* @throws IOException
* the io exception
*/
public GHHook createWebHook(URL url) throws IOException {
return createWebHook(url, null);
}

View File

@@ -28,24 +28,37 @@ import java.util.Locale;
/**
* Permission for a user in a repository.
*
* @see <a href="https://developer.github.com/v3/repos/collaborators/#review-a-users-permission-level">API</a>
*/
/*package*/ class GHPermission {
class GHPermission {
private String permission;
private GHUser user;
/**
* Gets permission.
*
* @return one of {@code admin}, {@code write}, {@code read}, or {@code none}
*/
public String getPermission() {
return permission;
}
/**
* Gets permission type.
*
* @return the permission type
*/
public GHPermissionType getPermissionType() {
return Enum.valueOf(GHPermissionType.class, permission.toUpperCase(Locale.ENGLISH));
}
/**
* Gets user.
*
* @return the user
*/
public GHUser getUser() {
return user;
}

View File

@@ -1,11 +1,10 @@
package org.kohsuke.github;
/**
* The enum GHPermissionType.
*
* @author Kohsuke Kawaguchi
*/
public enum GHPermissionType {
ADMIN,
WRITE,
READ,
NONE
ADMIN, WRITE, READ, NONE
}

View File

@@ -13,32 +13,35 @@ import java.util.TreeMap;
/**
* Common part of {@link GHUser} and {@link GHOrganization}.
*
*
* @author Kohsuke Kawaguchi
*/
public abstract class GHPerson extends GHObject {
/*package almost final*/ GitHub root;
/* package almost final */ GitHub root;
// core data fields that exist even for "small" user data (such as the user info in pull request)
protected String login, avatar_url, gravatar_id;
// other fields (that only show up in full data)
protected String location,blog,email,name,company;
protected String location, blog, email, name, company;
protected String html_url;
protected int followers,following,public_repos,public_gists;
protected int followers, following, public_repos, public_gists;
/*package*/ GHPerson wrapUp(GitHub root) {
GHPerson wrapUp(GitHub root) {
this.root = root;
return this;
}
/**
* Fully populate the data by retrieving missing data.
*
* <p>
* Depending on the original API call where this object is created, it may not contain everything.
*
* @throws IOException
* the io exception
*/
protected synchronized void populate() throws IOException {
if (created_at!=null) {
if (created_at != null) {
return; // already populated
}
if (root == null || root.isOffline()) {
@@ -51,64 +54,66 @@ public abstract class GHPerson extends GHObject {
* Gets the public repositories this user owns.
*
* <p>
* To list your own repositories, including private repositories,
* use {@link GHMyself#listRepositories()}
* To list your own repositories, including private repositories, use {@link GHMyself#listRepositories()}
*
* @return the repositories
* @throws IOException
* the io exception
*/
public synchronized Map<String,GHRepository> getRepositories() throws IOException {
Map<String,GHRepository> repositories = new TreeMap<String, GHRepository>();
public synchronized Map<String, GHRepository> getRepositories() throws IOException {
Map<String, GHRepository> repositories = new TreeMap<String, GHRepository>();
for (GHRepository r : listRepositories(100)) {
repositories.put(r.getName(),r);
repositories.put(r.getName(), r);
}
return Collections.unmodifiableMap(repositories);
}
/**
* Lists up all the repositories using a 30 items page size.
*
* <p>
* Unlike {@link #getRepositories()}, this does not wait until all the repositories are returned.
*
* @return the paged iterable
*/
public PagedIterable<GHRepository> listRepositories() {
return listRepositories(30);
return listRepositories(30);
}
/**
* Lists up all the repositories using the specified page size.
*
* @param pageSize size for each page of items returned by GitHub. Maximum page size is 100.
*
* Unlike {@link #getRepositories()}, this does not wait until all the repositories are returned.
* @param pageSize
* size for each page of items returned by GitHub. Maximum page size is 100. Unlike
* {@link #getRepositories()}, this does not wait until all the repositories are returned.
* @return the paged iterable
*/
public PagedIterable<GHRepository> listRepositories(final int pageSize) {
return new PagedIterable<GHRepository>() {
public PagedIterator<GHRepository> _iterator(int pageSize) {
return new PagedIterator<GHRepository>(root.retrieve().asIterator("/users/" + login + "/repos?per_page=" + pageSize, GHRepository[].class, pageSize)) {
@Override
protected void wrapUp(GHRepository[] page) {
for (GHRepository c : page)
c.wrap(root);
}
};
}
};
return root.retrieve()
.asPagedIterable("/users/" + login + "/repos", GHRepository[].class, item -> item.wrap(root))
.withPageSize(pageSize);
}
/**
* Loads repository list in a paginated fashion.
*
* <p>
* For a person with a lot of repositories, GitHub returns the list of repositories in a paginated fashion.
* Unlike {@link #getRepositories()}, this method allows the caller to start processing data as it arrives.
*
* Every {@link Iterator#next()} call results in I/O. Exceptions that occur during the processing is wrapped
* into {@link Error}.
*
* @deprecated
* Use {@link #listRepositories()}
* <p>
* For a person with a lot of repositories, GitHub returns the list of repositories in a paginated fashion. Unlike
* {@link #getRepositories()}, this method allows the caller to start processing data as it arrives.
* <p>
* Every {@link Iterator#next()} call results in I/O. Exceptions that occur during the processing is wrapped into
* {@link Error}.
*
* @param pageSize
* the page size
* @return the iterable
* @deprecated Use {@link #listRepositories()}
*/
@Deprecated
public synchronized Iterable<List<GHRepository>> iterateRepositories(final int pageSize) {
return new Iterable<List<GHRepository>>() {
public Iterator<List<GHRepository>> iterator() {
final Iterator<GHRepository[]> pager = root.retrieve().asIterator("/users/" + login + "/repos?per_page="+pageSize,GHRepository[].class, pageSize);
final Iterator<GHRepository[]> pager = root.retrieve()
.asIterator("/users/" + login + "/repos", GHRepository[].class, pageSize);
return new Iterator<List<GHRepository>>() {
public boolean hasNext() {
@@ -131,9 +136,13 @@ public abstract class GHPerson extends GHObject {
}
/**
* Gets repository.
*
* @return
* null if the repository was not found
* @param name
* the name
* @return null if the repository was not found
* @throws IOException
* the io exception
*/
public GHRepository getRepository(String name) throws IOException {
try {
@@ -145,33 +154,41 @@ public abstract class GHPerson extends GHObject {
/**
* Lists events for an organization or an user.
*
* @return the paged iterable
* @throws IOException
* the io exception
*/
public abstract PagedIterable<GHEventInfo> listEvents() throws IOException;
/**
* Gravatar ID of this user, like 0cb9832a01c22c083390f3c5dcb64105
*
* @deprecated
* No longer available in the v3 API.
* @return the gravatar id
* @deprecated No longer available in the v3 API.
*/
public String getGravatarId() {
return gravatar_id;
}
/**
* Returns a string like 'https://secure.gravatar.com/avatar/0cb9832a01c22c083390f3c5dcb64105'
* that indicates the avatar image URL.
* Returns a string like 'https://secure.gravatar.com/avatar/0cb9832a01c22c083390f3c5dcb64105' that indicates the
* avatar image URL.
*
* @return the avatar url
*/
public String getAvatarUrl() {
if (avatar_url!=null)
if (avatar_url != null)
return avatar_url;
if (gravatar_id!=null)
return "https://secure.gravatar.com/avatar/"+gravatar_id;
if (gravatar_id != null)
return "https://secure.gravatar.com/avatar/" + gravatar_id;
return null;
}
/**
* Gets the login ID of this user, like 'kohsuke'
*
* @return the login
*/
public String getLogin() {
return login;
@@ -179,6 +196,10 @@ public abstract class GHPerson extends GHObject {
/**
* Gets the human-readable name of the user, like "Kohsuke Kawaguchi"
*
* @return the name
* @throws IOException
* the io exception
*/
public String getName() throws IOException {
populate();
@@ -187,6 +208,10 @@ public abstract class GHPerson extends GHObject {
/**
* Gets the company name of this user, like "Sun Microsystems, Inc."
*
* @return the company
* @throws IOException
* the io exception
*/
public String getCompany() throws IOException {
populate();
@@ -195,6 +220,10 @@ public abstract class GHPerson extends GHObject {
/**
* Gets the location of this user, like "Santa Clara, California"
*
* @return the location
* @throws IOException
* the io exception
*/
public String getLocation() throws IOException {
populate();
@@ -213,6 +242,10 @@ public abstract class GHPerson extends GHObject {
/**
* Gets the blog URL of this user.
*
* @return the blog
* @throws IOException
* the io exception
*/
public String getBlog() throws IOException {
populate();
@@ -226,27 +259,59 @@ public abstract class GHPerson extends GHObject {
/**
* Gets the e-mail address of the user.
*
* @return the email
* @throws IOException
* the io exception
*/
public String getEmail() throws IOException {
populate();
return email;
}
/**
* Gets public gist count.
*
* @return the public gist count
* @throws IOException
* the io exception
*/
public int getPublicGistCount() throws IOException {
populate();
return public_gists;
}
/**
* Gets public repo count.
*
* @return the public repo count
* @throws IOException
* the io exception
*/
public int getPublicRepoCount() throws IOException {
populate();
return public_repos;
}
/**
* Gets following count.
*
* @return the following count
* @throws IOException
* the io exception
*/
public int getFollowingCount() throws IOException {
populate();
return following;
}
/**
* Gets followers count.
*
* @return the followers count
* @throws IOException
* the io exception
*/
public int getFollowersCount() throws IOException {
populate();
return followers;

View File

@@ -6,38 +6,73 @@ import java.util.HashSet;
/**
* Set of {@link GHPerson} with helper lookup methods.
*
*
* @param <T>
* the type parameter
* @author Kohsuke Kawaguchi
*/
public class GHPersonSet<T extends GHPerson> extends HashSet<T> {
private static final long serialVersionUID = 1L;
/**
* Instantiates a new Gh person set.
*/
public GHPersonSet() {
}
/**
* Instantiates a new Gh person set.
*
* @param c
* the c
*/
public GHPersonSet(Collection<? extends T> c) {
super(c);
}
/**
* Instantiates a new Gh person set.
*
* @param c
* the c
*/
public GHPersonSet(T... c) {
super(Arrays.asList(c));
}
/**
* Instantiates a new Gh person set.
*
* @param initialCapacity
* the initial capacity
* @param loadFactor
* the load factor
*/
public GHPersonSet(int initialCapacity, float loadFactor) {
super(initialCapacity, loadFactor);
}
/**
* Instantiates a new Gh person set.
*
* @param initialCapacity
* the initial capacity
*/
public GHPersonSet(int initialCapacity) {
super(initialCapacity);
}
/**
* Finds the item by its login.
*
* @param login
* the login
* @return the t
*/
public T byLogin(String login) {
for (T t : this)
if (t.getLogin().equals(login))
return t;
return null;
}
}
}

View File

@@ -0,0 +1,309 @@
/*
* The MIT License
*
* Copyright 2018 Martin van Zijl.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package org.kohsuke.github;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URL;
import java.util.Locale;
import static org.kohsuke.github.Previews.INERTIA;
/**
* A GitHub project.
*
* @author Martin van Zijl
* @see <a href="https://developer.github.com/v3/projects/">Projects</a>
*/
public class GHProject extends GHObject {
protected GitHub root;
protected GHObject owner;
private String owner_url;
private String html_url;
private String node_id;
private String name;
private String body;
private int number;
private String state;
private GHUser creator;
@Override
public URL getHtmlUrl() throws IOException {
return GitHub.parseURL(html_url);
}
/**
* Gets root.
*
* @return the root
*/
public GitHub getRoot() {
return root;
}
/**
* Gets owner.
*
* @return the owner
* @throws IOException
* the io exception
*/
public GHObject getOwner() throws IOException {
if (owner == null) {
try {
if (owner_url.contains("/orgs/")) {
owner = root.retrieve().to(getOwnerUrl().getPath(), GHOrganization.class).wrapUp(root);
} else if (owner_url.contains("/users/")) {
owner = root.retrieve().to(getOwnerUrl().getPath(), GHUser.class).wrapUp(root);
} else if (owner_url.contains("/repos/")) {
owner = root.retrieve().to(getOwnerUrl().getPath(), GHRepository.class).wrap(root);
}
} catch (FileNotFoundException e) {
return null;
}
}
return owner;
}
/**
* Gets owner url.
*
* @return the owner url
*/
public URL getOwnerUrl() {
return GitHub.parseURL(owner_url);
}
/**
* Gets node id.
*
* @return the node id
*/
public String getNode_id() {
return node_id;
}
/**
* Gets name.
*
* @return the name
*/
public String getName() {
return name;
}
/**
* Gets body.
*
* @return the body
*/
public String getBody() {
return body;
}
/**
* Gets number.
*
* @return the number
*/
public int getNumber() {
return number;
}
/**
* Gets state.
*
* @return the state
*/
public ProjectState getState() {
return Enum.valueOf(ProjectState.class, state.toUpperCase(Locale.ENGLISH));
}
/**
* Gets creator.
*
* @return the creator
*/
public GHUser getCreator() {
return creator;
}
/**
* Wrap gh project.
*
* @param repo
* the repo
* @return the gh project
*/
public GHProject wrap(GHRepository repo) {
this.owner = repo;
this.root = repo.root;
return this;
}
/**
* Wrap gh project.
*
* @param root
* the root
* @return the gh project
*/
public GHProject wrap(GitHub root) {
this.root = root;
return this;
}
private void edit(String key, Object value) throws IOException {
new Requester(root).withPreview(INERTIA).with(key, value).method("PATCH").to(getApiRoute());
}
/**
* Gets api route.
*
* @return the api route
*/
protected String getApiRoute() {
return "/projects/" + id;
}
/**
* Sets name.
*
* @param name
* the name
* @throws IOException
* the io exception
*/
public void setName(String name) throws IOException {
edit("name", name);
}
/**
* Sets body.
*
* @param body
* the body
* @throws IOException
* the io exception
*/
public void setBody(String body) throws IOException {
edit("body", body);
}
/**
* The enum ProjectState.
*/
public enum ProjectState {
OPEN, CLOSED
}
/**
* Sets state.
*
* @param state
* the state
* @throws IOException
* the io exception
*/
public void setState(ProjectState state) throws IOException {
edit("state", state.toString().toLowerCase());
}
/**
* The enum ProjectStateFilter.
*/
public static enum ProjectStateFilter {
ALL, OPEN, CLOSED
}
/**
* Set the permission level that all members of the project's organization will have on this project. Only
* applicable for organization-owned projects.
*
* @param permission
* the permission
* @throws IOException
* the io exception
*/
public void setOrganizationPermission(GHPermissionType permission) throws IOException {
edit("organization_permission", permission.toString().toLowerCase());
}
/**
* Sets visibility of the project within the organization. Only applicable for organization-owned projects.
*
* @param isPublic
* the is public
* @throws IOException
* the io exception
*/
public void setPublic(boolean isPublic) throws IOException {
edit("public", isPublic);
}
/**
* Delete.
*
* @throws IOException
* the io exception
*/
public void delete() throws IOException {
new Requester(root).withPreview(INERTIA).method("DELETE").to(getApiRoute());
}
/**
* List columns paged iterable.
*
* @return the paged iterable
* @throws IOException
* the io exception
*/
public PagedIterable<GHProjectColumn> listColumns() throws IOException {
final GHProject project = this;
return root.retrieve()
.withPreview(INERTIA)
.asPagedIterable(String.format("/projects/%d/columns", id),
GHProjectColumn[].class,
item -> item.wrap(project));
}
/**
* Create column gh project column.
*
* @param name
* the name
* @return the gh project column
* @throws IOException
* the io exception
*/
public GHProjectColumn createColumn(String name) throws IOException {
return root.retrieve()
.method("POST")
.withPreview(INERTIA)
.with("name", name)
.to(String.format("/projects/%d/columns", id), GHProjectColumn.class)
.wrap(this);
}
}

View File

@@ -0,0 +1,222 @@
package org.kohsuke.github;
import org.apache.commons.lang3.StringUtils;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URL;
import static org.kohsuke.github.Previews.INERTIA;
/**
* The type GHProjectCard.
*
* @author Gunnar Skjold
*/
public class GHProjectCard extends GHObject {
private GitHub root;
private GHProject project;
private GHProjectColumn column;
private String note;
private GHUser creator;
private String content_url, project_url, column_url;
private boolean archived;
public URL getHtmlUrl() throws IOException {
return null;
}
/**
* Wrap gh project card.
*
* @param root
* the root
* @return the gh project card
*/
public GHProjectCard wrap(GitHub root) {
this.root = root;
return this;
}
/**
* Wrap gh project card.
*
* @param column
* the column
* @return the gh project card
*/
public GHProjectCard wrap(GHProjectColumn column) {
this.column = column;
this.project = column.project;
this.root = column.root;
return this;
}
/**
* Gets root.
*
* @return the root
*/
public GitHub getRoot() {
return root;
}
/**
* Gets project.
*
* @return the project
* @throws IOException
* the io exception
*/
public GHProject getProject() throws IOException {
if (project == null) {
try {
project = root.retrieve().to(getProjectUrl().getPath(), GHProject.class).wrap(root);
} catch (FileNotFoundException e) {
return null;
}
}
return project;
}
/**
* Gets column.
*
* @return the column
* @throws IOException
* the io exception
*/
public GHProjectColumn getColumn() throws IOException {
if (column == null) {
try {
column = root.retrieve().to(getColumnUrl().getPath(), GHProjectColumn.class).wrap(root);
} catch (FileNotFoundException e) {
return null;
}
}
return column;
}
/**
* Gets content.
*
* @return the content
* @throws IOException
* the io exception
*/
public GHIssue getContent() throws IOException {
if (StringUtils.isEmpty(content_url))
return null;
try {
if (content_url.contains("/pulls")) {
return root.retrieve().to(getContentUrl().getPath(), GHPullRequest.class).wrap(root);
} else {
return root.retrieve().to(getContentUrl().getPath(), GHIssue.class).wrap(root);
}
} catch (FileNotFoundException e) {
return null;
}
}
/**
* Gets note.
*
* @return the note
*/
public String getNote() {
return note;
}
/**
* Gets creator.
*
* @return the creator
*/
public GHUser getCreator() {
return creator;
}
/**
* Gets content url.
*
* @return the content url
*/
public URL getContentUrl() {
return GitHub.parseURL(content_url);
}
/**
* Gets project url.
*
* @return the project url
*/
public URL getProjectUrl() {
return GitHub.parseURL(project_url);
}
/**
* Gets column url.
*
* @return the column url
*/
public URL getColumnUrl() {
return GitHub.parseURL(column_url);
}
/**
* Is archived boolean.
*
* @return the boolean
*/
public boolean isArchived() {
return archived;
}
/**
* Sets note.
*
* @param note
* the note
* @throws IOException
* the io exception
*/
public void setNote(String note) throws IOException {
edit("note", note);
}
/**
* Sets archived.
*
* @param archived
* the archived
* @throws IOException
* the io exception
*/
public void setArchived(boolean archived) throws IOException {
edit("archived", archived);
}
private void edit(String key, Object value) throws IOException {
new Requester(root).withPreview(INERTIA).with(key, value).method("PATCH").to(getApiRoute());
}
/**
* Gets api route.
*
* @return the api route
*/
protected String getApiRoute() {
return String.format("/projects/columns/cards/%d", id);
}
/**
* Delete.
*
* @throws IOException
* the io exception
*/
public void delete() throws IOException {
new Requester(root).withPreview(INERTIA).method("DELETE").to(getApiRoute());
}
}

View File

@@ -0,0 +1,183 @@
package org.kohsuke.github;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URL;
import static org.kohsuke.github.Previews.INERTIA;
/**
* The type GHProjectColumn.
*
* @author Gunnar Skjold
*/
public class GHProjectColumn extends GHObject {
protected GitHub root;
protected GHProject project;
private String name;
private String project_url;
@Override
public URL getHtmlUrl() throws IOException {
return null;
}
/**
* Wrap gh project column.
*
* @param root
* the root
* @return the gh project column
*/
public GHProjectColumn wrap(GitHub root) {
this.root = root;
return this;
}
/**
* Wrap gh project column.
*
* @param project
* the project
* @return the gh project column
*/
public GHProjectColumn wrap(GHProject project) {
this.project = project;
this.root = project.root;
return this;
}
/**
* Gets root.
*
* @return the root
*/
public GitHub getRoot() {
return root;
}
/**
* Gets project.
*
* @return the project
* @throws IOException
* the io exception
*/
public GHProject getProject() throws IOException {
if (project == null) {
try {
project = root.retrieve().to(getProjectUrl().getPath(), GHProject.class).wrap(root);
} catch (FileNotFoundException e) {
return null;
}
}
return project;
}
/**
* Gets name.
*
* @return the name
*/
public String getName() {
return name;
}
/**
* Gets project url.
*
* @return the project url
*/
public URL getProjectUrl() {
return GitHub.parseURL(project_url);
}
/**
* Sets name.
*
* @param name
* the name
* @throws IOException
* the io exception
*/
public void setName(String name) throws IOException {
edit("name", name);
}
private void edit(String key, Object value) throws IOException {
new Requester(root).withPreview(INERTIA).with(key, value).method("PATCH").to(getApiRoute());
}
/**
* Gets api route.
*
* @return the api route
*/
protected String getApiRoute() {
return String.format("/projects/columns/%d", id);
}
/**
* Delete.
*
* @throws IOException
* the io exception
*/
public void delete() throws IOException {
new Requester(root).withPreview(INERTIA).method("DELETE").to(getApiRoute());
}
/**
* List cards paged iterable.
*
* @return the paged iterable
* @throws IOException
* the io exception
*/
public PagedIterable<GHProjectCard> listCards() throws IOException {
final GHProjectColumn column = this;
return root.retrieve()
.withPreview(INERTIA)
.asPagedIterable(String.format("/projects/columns/%d/cards", id),
GHProjectCard[].class,
item -> item.wrap(column));
}
/**
* Create card gh project card.
*
* @param note
* the note
* @return the gh project card
* @throws IOException
* the io exception
*/
public GHProjectCard createCard(String note) throws IOException {
return root.retrieve()
.method("POST")
.withPreview(INERTIA)
.with("note", note)
.to(String.format("/projects/columns/%d/cards", id), GHProjectCard.class)
.wrap(this);
}
/**
* Create card gh project card.
*
* @param issue
* the issue
* @return the gh project card
* @throws IOException
* the io exception
*/
public GHProjectCard createCard(GHIssue issue) throws IOException {
return root.retrieve()
.method("POST")
.withPreview(INERTIA)
.with("content_type", issue instanceof GHPullRequest ? "PullRequest" : "Issue")
.with("content_id", issue.getId())
.to(String.format("/projects/columns/%d/cards", id), GHProjectCard.class)
.wrap(this);
}
}

View File

@@ -23,24 +23,30 @@
*/
package org.kohsuke.github;
import javax.annotation.CheckForNull;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import javax.annotation.CheckForNull;
import static org.kohsuke.github.Previews.SHADOW_CAT;
/**
* A pull request.
*
* @author Kohsuke Kawaguchi
* @see GHRepository#getPullRequest(int)
* @see GHRepository#getPullRequest(int) GHRepository#getPullRequest(int)
*/
@SuppressWarnings({"UnusedDeclaration"})
public class GHPullRequest extends GHIssue {
@SuppressWarnings({ "UnusedDeclaration" })
public class GHPullRequest extends GHIssue implements Refreshable {
private static final String COMMENTS_ACTION = "/comments";
private static final String REQUEST_REVIEWERS = "/requested_reviewers";
private String patch_url, diff_url, issue_url;
private GHCommitPointer base;
@@ -51,57 +57,73 @@ public class GHPullRequest extends GHIssue {
private GHUser merged_by;
private int review_comments, additions, commits;
private boolean merged, maintainer_can_modify;
// making these package private to all for testing
boolean draft;
private Boolean mergeable;
private int deletions;
private String mergeable_state;
private int changed_files;
private String merge_commit_sha;
// pull request reviewers
private GHUser[] requested_reviewers;
private GHTeam[] requested_teams;
/**
* GitHub doesn't return some properties of {@link GHIssue} when requesting the GET on the 'pulls' API
* route as opposed to 'issues' API route. This flag remembers whether we made the GET call on the 'issues' route
* on this object to fill in those missing details
* GitHub doesn't return some properties of {@link GHIssue} when requesting the GET on the 'pulls' API route as
* opposed to 'issues' API route. This flag remembers whether we made the GET call on the 'issues' route on this
* object to fill in those missing details
*/
private transient boolean fetchedIssueDetails;
GHPullRequest wrapUp(GHRepository owner) {
this.wrap(owner);
return wrapUp(owner.root);
}
GHPullRequest wrapUp(GitHub root) {
if (owner != null) owner.wrap(root);
if (base != null) base.wrapUp(root);
if (head != null) head.wrapUp(root);
if (merged_by != null) merged_by.wrapUp(root);
if (owner != null)
owner.wrap(root);
if (base != null)
base.wrapUp(root);
if (head != null)
head.wrapUp(root);
if (merged_by != null)
merged_by.wrapUp(root);
if (requested_reviewers != null)
GHUser.wrap(requested_reviewers, root);
if (requested_teams != null)
GHTeam.wrapUp(requested_teams, this);
return this;
}
@Override
protected String getApiRoute() {
return "/repos/"+owner.getOwnerName()+"/"+owner.getName()+"/pulls/"+number;
return "/repos/" + owner.getOwnerName() + "/" + owner.getName() + "/pulls/" + number;
}
/**
* The URL of the patch file.
* like https://github.com/jenkinsci/jenkins/pull/100.patch
* The URL of the patch file. like https://github.com/jenkinsci/jenkins/pull/100.patch
*
* @return the patch url
*/
public URL getPatchUrl() {
return GitHub.parseURL(patch_url);
}
/**
* The URL of the patch file.
* like https://github.com/jenkinsci/jenkins/pull/100.patch
* The URL of the patch file. like https://github.com/jenkinsci/jenkins/pull/100.patch
*
* @return the issue url
*/
public URL getIssueUrl() {
return GitHub.parseURL(issue_url);
}
/**
* This points to where the change should be pulled into,
* but I'm not really sure what exactly it means.
* This points to where the change should be pulled into, but I'm not really sure what exactly it means.
*
* @return the base
*/
public GHCommitPointer getBase() {
return base;
@@ -109,24 +131,39 @@ public class GHPullRequest extends GHIssue {
/**
* The change that should be pulled. The tip of the commits to merge.
*
* @return the head
*/
public GHCommitPointer getHead() {
return head;
}
/**
* Gets issue updated at.
*
* @return the issue updated at
* @throws IOException
* the io exception
*/
@Deprecated
public Date getIssueUpdatedAt() throws IOException {
return super.getUpdatedAt();
}
/**
* The diff file,
* like https://github.com/jenkinsci/jenkins/pull/100.diff
* The diff file, like https://github.com/jenkinsci/jenkins/pull/100.diff
*
* @return the diff url
*/
public URL getDiffUrl() {
return GitHub.parseURL(diff_url);
}
/**
* Gets merged at.
*
* @return the merged at
*/
public Date getMergedAt() {
return GitHub.parseDate(merged_at);
}
@@ -151,60 +188,143 @@ public class GHPullRequest extends GHIssue {
// details that are only available via get with ID
//
/**
* Gets merged by.
*
* @return the merged by
* @throws IOException
* the io exception
*/
public GHUser getMergedBy() throws IOException {
populate();
return merged_by;
}
/**
* Gets review comments.
*
* @return the review comments
* @throws IOException
* the io exception
*/
public int getReviewComments() throws IOException {
populate();
return review_comments;
}
/**
* Gets additions.
*
* @return the additions
* @throws IOException
* the io exception
*/
public int getAdditions() throws IOException {
populate();
return additions;
}
/**
* Gets commits.
*
* @return the commits
* @throws IOException
* the io exception
*/
public int getCommits() throws IOException {
populate();
return commits;
}
/**
* Is merged boolean.
*
* @return the boolean
* @throws IOException
* the io exception
*/
public boolean isMerged() throws IOException {
populate();
return merged;
}
/**
* Can maintainer modify boolean.
*
* @return the boolean
* @throws IOException
* the io exception
*/
public boolean canMaintainerModify() throws IOException {
populate();
return maintainer_can_modify;
}
/**
* Is draft boolean.
*
* @return the boolean
* @throws IOException
* the io exception
*/
public boolean isDraft() throws IOException {
populate();
return draft;
}
/**
* Is this PR mergeable?
*
* @return
* null if the state has not been determined yet, for example when a PR is newly created.
* If this method is called on an instance whose mergeable state is not yet known,
* API call is made to retrieve the latest state.
* @return null if the state has not been determined yet, for example when a PR is newly created. If this method is
* called on an instance whose mergeable state is not yet known, API call is made to retrieve the latest
* state.
* @throws IOException
* the io exception
*/
public Boolean getMergeable() throws IOException {
if (mergeable==null)
refresh();
refresh(mergeable);
return mergeable;
}
/**
* for test purposes only
*/
@Deprecated
Boolean getMergeableNoRefresh() throws IOException {
return mergeable;
}
/**
* Gets deletions.
*
* @return the deletions
* @throws IOException
* the io exception
*/
public int getDeletions() throws IOException {
populate();
return deletions;
}
/**
* Gets mergeable state.
*
* @return the mergeable state
* @throws IOException
* the io exception
*/
public String getMergeableState() throws IOException {
populate();
return mergeable_state;
}
/**
* Gets changed files.
*
* @return the changed files
* @throws IOException
* the io exception
*/
public int getChangedFiles() throws IOException {
populate();
return changed_files;
@@ -212,19 +332,48 @@ public class GHPullRequest extends GHIssue {
/**
* See <a href="https://developer.github.com/changes/2013-04-25-deprecating-merge-commit-sha">GitHub blog post</a>
*
* @return the merge commit sha
* @throws IOException
* the io exception
*/
public String getMergeCommitSha() throws IOException {
populate();
return merge_commit_sha;
}
/**
* Gets requested reviewers.
*
* @return the requested reviewers
* @throws IOException
* the io exception
*/
public List<GHUser> getRequestedReviewers() throws IOException {
refresh(requested_reviewers);
return Collections.unmodifiableList(Arrays.asList(requested_reviewers));
}
/**
* Gets requested teams.
*
* @return the requested teams
* @throws IOException
* the io exception
*/
public List<GHTeam> getRequestedTeams() throws IOException {
refresh(requested_teams);
return Collections.unmodifiableList(Arrays.asList(requested_teams));
}
/**
* Fully populate the data by retrieving missing data.
*
* Depending on the original API call where this object is created, it may not contain everything.
*/
private void populate() throws IOException {
if (mergeable_state!=null) return; // already populated
if (mergeable_state != null)
return; // already populated
refresh();
}
@@ -235,96 +384,94 @@ public class GHPullRequest extends GHIssue {
if (root.isOffline()) {
return; // cannot populate, will have to live with what we have
}
root.retrieve().to(url, this).wrapUp(owner);
root.retrieve().withPreview(SHADOW_CAT).to(url, this).wrapUp(owner);
}
/**
* Retrieves all the files associated to this pull request.
*
* @return the paged iterable
*/
public PagedIterable<GHPullRequestFileDetail> listFiles() {
return new PagedIterable<GHPullRequestFileDetail>() {
public PagedIterator<GHPullRequestFileDetail> _iterator(int pageSize) {
return new PagedIterator<GHPullRequestFileDetail>(root.retrieve().asIterator(String.format("%s/files", getApiRoute()),
GHPullRequestFileDetail[].class, pageSize)) {
@Override
protected void wrapUp(GHPullRequestFileDetail[] page) {
}
};
}
};
return root.retrieve()
.asPagedIterable(String.format("%s/files", getApiRoute()), GHPullRequestFileDetail[].class, null);
}
/**
* Retrieves all the reviews associated to this pull request.
*
* @return the paged iterable
*/
public PagedIterable<GHPullRequestReview> listReviews() {
return new PagedIterable<GHPullRequestReview>() {
public PagedIterator<GHPullRequestReview> _iterator(int pageSize) {
return new PagedIterator<GHPullRequestReview>(root.retrieve()
.asIterator(String.format("%s/reviews", getApiRoute()),
GHPullRequestReview[].class, pageSize)) {
@Override
protected void wrapUp(GHPullRequestReview[] page) {
for (GHPullRequestReview r: page) {
r.wrapUp(GHPullRequest.this);
}
}
};
}
};
return root.retrieve()
.asPagedIterable(String.format("%s/reviews", getApiRoute()),
GHPullRequestReview[].class,
item -> item.wrapUp(GHPullRequest.this));
}
/**
* Obtains all the review comments associated with this pull request.
*
* @return the paged iterable
* @throws IOException
* the io exception
*/
public PagedIterable<GHPullRequestReviewComment> listReviewComments() throws IOException {
return new PagedIterable<GHPullRequestReviewComment>() {
public PagedIterator<GHPullRequestReviewComment> _iterator(int pageSize) {
return new PagedIterator<GHPullRequestReviewComment>(root.retrieve().asIterator(getApiRoute() + COMMENTS_ACTION,
GHPullRequestReviewComment[].class, pageSize)) {
protected void wrapUp(GHPullRequestReviewComment[] page) {
for (GHPullRequestReviewComment c : page)
c.wrapUp(GHPullRequest.this);
}
};
}
};
return root.retrieve()
.asPagedIterable(getApiRoute() + COMMENTS_ACTION,
GHPullRequestReviewComment[].class,
item -> item.wrapUp(GHPullRequest.this));
}
/**
* Retrieves all the commits associated to this pull request.
*
* @return the paged iterable
*/
public PagedIterable<GHPullRequestCommitDetail> listCommits() {
return new PagedIterable<GHPullRequestCommitDetail>() {
public PagedIterator<GHPullRequestCommitDetail> _iterator(int pageSize) {
return new PagedIterator<GHPullRequestCommitDetail>(root.retrieve().asIterator(
String.format("%s/commits", getApiRoute()),
GHPullRequestCommitDetail[].class, pageSize)) {
@Override
protected void wrapUp(GHPullRequestCommitDetail[] page) {
for (GHPullRequestCommitDetail c : page)
c.wrapUp(GHPullRequest.this);
}
};
}
};
return root.retrieve()
.asPagedIterable(String.format("%s/commits", getApiRoute()),
GHPullRequestCommitDetail[].class,
item -> item.wrapUp(GHPullRequest.this));
}
/**
* @deprecated
* Use {@link #createReview()}
* Create review gh pull request review.
*
* @param body
* the body
* @param event
* the event
* @param comments
* the comments
* @return the gh pull request review
* @throws IOException
* the io exception
* @deprecated Use {@link #createReview()}
*/
public GHPullRequestReview createReview(String body, @CheckForNull GHPullRequestReviewState event,
GHPullRequestReviewComment... comments) throws IOException {
public GHPullRequestReview createReview(String body,
@CheckForNull GHPullRequestReviewState event,
GHPullRequestReviewComment... comments) throws IOException {
return createReview(body, event, Arrays.asList(comments));
}
/**
* @deprecated
* Use {@link #createReview()}
* Create review gh pull request review.
*
* @param body
* the body
* @param event
* the event
* @param comments
* the comments
* @return the gh pull request review
* @throws IOException
* the io exception
* @deprecated Use {@link #createReview()}
*/
public GHPullRequestReview createReview(String body, @CheckForNull GHPullRequestReviewState event,
List<GHPullRequestReviewComment> comments) throws IOException {
public GHPullRequestReview createReview(String body,
@CheckForNull GHPullRequestReviewState event,
List<GHPullRequestReviewComment> comments) throws IOException {
GHPullRequestReviewBuilder b = createReview().body(body);
for (GHPullRequestReviewComment c : comments) {
b.comment(c.getBody(), c.getPath(), c.getPosition());
@@ -332,40 +479,96 @@ public class GHPullRequest extends GHIssue {
return b.create();
}
/**
* Create review gh pull request review builder.
*
* @return the gh pull request review builder
*/
public GHPullRequestReviewBuilder createReview() {
return new GHPullRequestReviewBuilder(this);
}
public GHPullRequestReviewComment createReviewComment(String body, String sha, String path, int position) throws IOException {
/**
* Create review comment gh pull request review comment.
*
* @param body
* the body
* @param sha
* the sha
* @param path
* the path
* @param position
* the position
* @return the gh pull request review comment
* @throws IOException
* the io exception
*/
public GHPullRequestReviewComment createReviewComment(String body, String sha, String path, int position)
throws IOException {
return new Requester(root).method("POST")
.with("body", body)
.with("commit_id", sha)
.with("path", path)
.with("position", position)
.to(getApiRoute() + COMMENTS_ACTION, GHPullRequestReviewComment.class).wrapUp(this);
.to(getApiRoute() + COMMENTS_ACTION, GHPullRequestReviewComment.class)
.wrapUp(this);
}
/**
* Request reviewers.
*
* @param reviewers
* the reviewers
* @throws IOException
* the io exception
*/
public void requestReviewers(List<GHUser> reviewers) throws IOException {
new Requester(root).method("POST")
.with("reviewers", getLogins(reviewers))
.to(getApiRoute() + REQUEST_REVIEWERS);
}
/**
* Request team reviewers.
*
* @param teams
* the teams
* @throws IOException
* the io exception
*/
public void requestTeamReviewers(List<GHTeam> teams) throws IOException {
List<String> teamReviewers = new ArrayList<String>(teams.size());
for (GHTeam team : teams) {
teamReviewers.add(team.getSlug());
}
new Requester(root).method("POST").with("team_reviewers", teamReviewers).to(getApiRoute() + REQUEST_REVIEWERS);
}
/**
* Merge this pull request.
*
* <p>
* The equivalent of the big green "Merge pull request" button.
*
* @param msg
* Commit message. If null, the default one will be used.
* Commit message. If null, the default one will be used.
* @throws IOException
* the io exception
*/
public void merge(String msg) throws IOException {
merge(msg,null);
merge(msg, null);
}
/**
* Merge this pull request.
*
* <p>
* The equivalent of the big green "Merge pull request" button.
*
* @param msg
* Commit message. If null, the default one will be used.
* Commit message. If null, the default one will be used.
* @param sha
* SHA that pull request head must match to allow merge.
* SHA that pull request head must match to allow merge.
* @throws IOException
* the io exception
*/
public void merge(String msg, String sha) throws IOException {
merge(msg, sha, null);
@@ -373,13 +576,17 @@ public class GHPullRequest extends GHIssue {
/**
* Merge this pull request, using the specified merge method.
*
* <p>
* The equivalent of the big green "Merge pull request" button.
*
* @param msg
* Commit message. If null, the default one will be used.
* Commit message. If null, the default one will be used.
* @param sha
* the sha
* @param method
* SHA that pull request head must match to allow merge.
* SHA that pull request head must match to allow merge.
* @throws IOException
* the io exception
*/
public void merge(String msg, String sha, MergeMethod method) throws IOException {
new Requester(root).method("PUT")
@@ -389,11 +596,16 @@ public class GHPullRequest extends GHIssue {
.to(getApiRoute() + "/merge");
}
public enum MergeMethod{ MERGE, SQUASH, REBASE }
/**
* The enum MergeMethod.
*/
public enum MergeMethod {
MERGE, SQUASH, REBASE
}
private void fetchIssue() throws IOException {
if (!fetchedIssueDetails) {
new Requester(root).to(getIssuesApiRoute(), this);
new Requester(root).method("GET").to(getIssuesApiRoute(), this);
fetchedIssueDetails = true;
}
}

View File

@@ -1,18 +1,18 @@
/*
* The MIT License
*
*
* Copyright (c) 2013, Luca Milanesio
*
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@@ -30,38 +30,58 @@ import java.net.URL;
/**
* Commit detail inside a {@link GHPullRequest}.
*
*
* @author Luca Milanesio
* @see GHPullRequest#listCommits()
* @see GHPullRequest#listCommits() GHPullRequest#listCommits()
*/
@SuppressFBWarnings(value = {"UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD",
"NP_UNWRITTEN_FIELD", "URF_UNREAD_FIELD"}, justification = "JSON API")
@SuppressFBWarnings(
value = { "UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD", "NP_UNWRITTEN_FIELD",
"URF_UNREAD_FIELD" },
justification = "JSON API")
public class GHPullRequestCommitDetail {
private GHPullRequest owner;
/*package*/ void wrapUp(GHPullRequest owner) {
void wrapUp(GHPullRequest owner) {
this.owner = owner;
}
/**
* The type Authorship.
*
* @deprecated Use {@link GitUser}
*/
public static class Authorship extends GitUser {
}
/**
* The type Tree.
*/
public static class Tree {
String sha;
String url;
/**
* Gets sha.
*
* @return the sha
*/
public String getSha() {
return sha;
}
/**
* Gets url.
*
* @return the url
*/
public URL getUrl() {
return GitHub.parseURL(url);
}
}
/**
* The type Commit.
*/
public static class Commit {
Authorship author;
Authorship committer;
@@ -70,46 +90,94 @@ public class GHPullRequestCommitDetail {
String url;
int comment_count;
/**
* Gets author.
*
* @return the author
*/
@WithBridgeMethods(value = Authorship.class, castRequired = true)
public GitUser getAuthor() {
return author;
}
/**
* Gets committer.
*
* @return the committer
*/
@WithBridgeMethods(value = Authorship.class, castRequired = true)
public GitUser getCommitter() {
return committer;
}
/**
* Gets message.
*
* @return the message
*/
public String getMessage() {
return message;
}
/**
* Gets url.
*
* @return the url
*/
public URL getUrl() {
return GitHub.parseURL(url);
}
/**
* Gets comment count.
*
* @return the comment count
*/
public int getComment_count() {
return comment_count;
}
/**
* Gets tree.
*
* @return the tree
*/
public Tree getTree() {
return tree;
}
}
/**
* The type CommitPointer.
*/
public static class CommitPointer {
String sha;
String url;
String html_url;
/**
* Gets url.
*
* @return the url
*/
public URL getUrl() {
return GitHub.parseURL(url);
}
/**
* Gets html url.
*
* @return the html url
*/
public URL getHtml_url() {
return GitHub.parseURL(html_url);
}
/**
* Gets sha.
*
* @return the sha
*/
public String getSha() {
return sha;
}
@@ -122,26 +190,56 @@ public class GHPullRequestCommitDetail {
String comments_url;
CommitPointer[] parents;
/**
* Gets sha.
*
* @return the sha
*/
public String getSha() {
return sha;
}
/**
* Gets commit.
*
* @return the commit
*/
public Commit getCommit() {
return commit;
}
/**
* Gets api url.
*
* @return the api url
*/
public URL getApiUrl() {
return GitHub.parseURL(url);
}
/**
* Gets url.
*
* @return the url
*/
public URL getUrl() {
return GitHub.parseURL(html_url);
}
/**
* Gets comments url.
*
* @return the comments url
*/
public URL getCommentsUrl() {
return GitHub.parseURL(comments_url);
}
/**
* Get parents commit pointer [ ].
*
* @return the commit pointer [ ]
*/
public CommitPointer[] getParents() {
CommitPointer[] newValue = new CommitPointer[parents.length];
System.arraycopy(parents, 0, newValue, 0, parents.length);

View File

@@ -1,18 +1,18 @@
/*
* The MIT License
*
*
* Copyright (c) 2015, Julien Henry
*
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@@ -27,9 +27,9 @@ import java.net.URL;
/**
* File detail inside a {@link GHPullRequest}.
*
*
* @author Julien Henry
* @see GHPullRequest#listFiles()
* @see GHPullRequest#listFiles() GHPullRequest#listFiles()
*/
public class GHPullRequestFileDetail {
@@ -43,44 +43,104 @@ public class GHPullRequestFileDetail {
String raw_url;
String contents_url;
String patch;
String previous_filename;
/**
* Gets sha.
*
* @return the sha
*/
public String getSha() {
return sha;
}
/**
* Gets filename.
*
* @return the filename
*/
public String getFilename() {
return filename;
}
/**
* Gets status.
*
* @return the status
*/
public String getStatus() {
return status;
}
/**
* Gets additions.
*
* @return the additions
*/
public int getAdditions() {
return additions;
}
/**
* Gets deletions.
*
* @return the deletions
*/
public int getDeletions() {
return deletions;
}
/**
* Gets changes.
*
* @return the changes
*/
public int getChanges() {
return changes;
}
/**
* Gets blob url.
*
* @return the blob url
*/
public URL getBlobUrl() {
return GitHub.parseURL(blob_url);
}
/**
* Gets raw url.
*
* @return the raw url
*/
public URL getRawUrl() {
return GitHub.parseURL(raw_url);
}
/**
* Gets contents url.
*
* @return the contents url
*/
public URL getContentsUrl() {
return GitHub.parseURL(contents_url);
}
/**
* Gets patch.
*
* @return the patch
*/
public String getPatch() {
return patch;
}
/**
* Gets previous filename.
*
* @return the previous filename
*/
public String getPreviousFilename() {
return previous_filename;
}
}

View File

@@ -1,58 +1,94 @@
package org.kohsuke.github;
import static org.kohsuke.github.Previews.SHADOW_CAT;
/**
* Lists up pull requests with some filtering and sorting.
*
* @author Kohsuke Kawaguchi
* @see GHRepository#queryPullRequests()
* @see GHRepository#queryPullRequests() GHRepository#queryPullRequests()
*/
public class GHPullRequestQueryBuilder extends GHQueryBuilder<GHPullRequest> {
private final GHRepository repo;
/*package*/ GHPullRequestQueryBuilder(GHRepository repo) {
GHPullRequestQueryBuilder(GHRepository repo) {
super(repo.root);
this.repo = repo;
}
/**
* State gh pull request query builder.
*
* @param state
* the state
* @return the gh pull request query builder
*/
public GHPullRequestQueryBuilder state(GHIssueState state) {
req.with("state",state);
req.with("state", state);
return this;
}
/**
* Head gh pull request query builder.
*
* @param head
* the head
* @return the gh pull request query builder
*/
public GHPullRequestQueryBuilder head(String head) {
req.with("head",head);
if (head != null && !head.contains(":")) {
head = repo.getOwnerName() + ":" + head;
}
req.with("head", head);
return this;
}
/**
* Base gh pull request query builder.
*
* @param base
* the base
* @return the gh pull request query builder
*/
public GHPullRequestQueryBuilder base(String base) {
req.with("base",base);
req.with("base", base);
return this;
}
/**
* Sort gh pull request query builder.
*
* @param sort
* the sort
* @return the gh pull request query builder
*/
public GHPullRequestQueryBuilder sort(Sort sort) {
req.with("sort",sort);
req.with("sort", sort);
return this;
}
public enum Sort { CREATED, UPDATED, POPULARITY, LONG_RUNNING }
/**
* The enum Sort.
*/
public enum Sort {
CREATED, UPDATED, POPULARITY, LONG_RUNNING
}
/**
* Direction gh pull request query builder.
*
* @param d
* the d
* @return the gh pull request query builder
*/
public GHPullRequestQueryBuilder direction(GHDirection d) {
req.with("direction",d);
req.with("direction", d);
return this;
}
@Override
public PagedIterable<GHPullRequest> list() {
return new PagedIterable<GHPullRequest>() {
public PagedIterator<GHPullRequest> _iterator(int pageSize) {
return new PagedIterator<GHPullRequest>(req.asIterator(repo.getApiTailUrl("pulls"), GHPullRequest[].class, pageSize)) {
@Override
protected void wrapUp(GHPullRequest[] page) {
for (GHPullRequest pr : page)
pr.wrapUp(repo);
}
};
}
};
return req.withPreview(SHADOW_CAT)
.asPagedIterable(repo.getApiTailUrl("pulls"), GHPullRequest[].class, item -> item.wrapUp(repo));
}
}

View File

@@ -25,17 +25,19 @@ package org.kohsuke.github;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import javax.annotation.CheckForNull;
import java.io.IOException;
import java.net.URL;
import java.util.Date;
import javax.annotation.CheckForNull;
/**
* Review to a pull request.
*
* @see GHPullRequest#listReviews()
* @see GHPullRequest#listReviews() GHPullRequest#listReviews()
* @see GHPullRequestReviewBuilder
*/
@SuppressFBWarnings(value = {"UWF_UNWRITTEN_FIELD"}, justification = "JSON API")
@SuppressFBWarnings(value = { "UWF_UNWRITTEN_FIELD" }, justification = "JSON API")
public class GHPullRequestReview extends GHObject {
GHPullRequest owner;
@@ -43,14 +45,17 @@ public class GHPullRequestReview extends GHObject {
private GHUser user;
private String commit_id;
private GHPullRequestReviewState state;
private String submitted_at;
/*package*/ GHPullRequestReview wrapUp(GHPullRequest owner) {
GHPullRequestReview wrapUp(GHPullRequest owner) {
this.owner = owner;
return this;
}
/**
* Gets the pull request to which this review is associated.
*
* @return the parent
*/
public GHPullRequest getParent() {
return owner;
@@ -58,6 +63,8 @@ public class GHPullRequestReview extends GHObject {
/**
* The comment itself.
*
* @return the body
*/
public String getBody() {
return body;
@@ -65,15 +72,29 @@ public class GHPullRequestReview extends GHObject {
/**
* Gets the user who posted this review.
*
* @return the user
* @throws IOException
* the io exception
*/
public GHUser getUser() throws IOException {
return owner.root.getUser(user.getLogin());
}
/**
* Gets commit id.
*
* @return the commit id
*/
public String getCommitId() {
return commit_id;
}
/**
* Gets state.
*
* @return the state
*/
@CheckForNull
public GHPullRequestReviewState getState() {
return state;
@@ -84,65 +105,103 @@ public class GHPullRequestReview extends GHObject {
return null;
}
/**
* Gets api route.
*
* @return the api route
*/
protected String getApiRoute() {
return owner.getApiRoute()+"/reviews/"+id;
return owner.getApiRoute() + "/reviews/" + id;
}
/**
* @deprecated
* Former preview method that changed when it got public. Left here for backward compatibility.
* Use {@link #submit(String, GHPullRequestReviewEvent)}
* When was this resource created?
*
* @return the submitted at
* @throws IOException
* the io exception
*/
public Date getSubmittedAt() throws IOException {
return GitHub.parseDate(submitted_at);
}
/**
* Since this method does not exist, we forward this value.
*/
@Override
public Date getCreatedAt() throws IOException {
return getSubmittedAt();
}
/**
* Submit.
*
* @param body
* the body
* @param state
* the state
* @throws IOException
* the io exception
* @deprecated Former preview method that changed when it got public. Left here for backward compatibility. Use
* {@link #submit(String, GHPullRequestReviewEvent)}
*/
public void submit(String body, GHPullRequestReviewState state) throws IOException {
submit(body,state.toEvent());
submit(body, state.toEvent());
}
/**
* Updates the comment.
*
* @param body
* the body
* @param event
* the event
* @throws IOException
* the io exception
*/
public void submit(String body, GHPullRequestReviewEvent event) throws IOException {
new Requester(owner.root).method("POST")
.with("body", body)
.with("event", event.action())
.to(getApiRoute()+"/events",this);
.to(getApiRoute() + "/events", this);
this.body = body;
this.state = event.toState();
}
/**
* Deletes this review.
*
* @throws IOException
* the io exception
*/
public void delete() throws IOException {
new Requester(owner.root).method("DELETE")
.to(getApiRoute());
new Requester(owner.root).method("DELETE").to(getApiRoute());
}
/**
* Dismisses this review.
*
* @param message
* the message
* @throws IOException
* the io exception
*/
public void dismiss(String message) throws IOException {
new Requester(owner.root).method("PUT")
.with("message", message)
.to(getApiRoute()+"/dismissals");
new Requester(owner.root).method("PUT").with("message", message).to(getApiRoute() + "/dismissals");
state = GHPullRequestReviewState.DISMISSED;
}
/**
* Obtains all the review comments associated with this pull request review.
*
* @return the paged iterable
* @throws IOException
* the io exception
*/
public PagedIterable<GHPullRequestReviewComment> listReviewComments() throws IOException {
return new PagedIterable<GHPullRequestReviewComment>() {
public PagedIterator<GHPullRequestReviewComment> _iterator(int pageSize) {
return new PagedIterator<GHPullRequestReviewComment>(
owner.root.retrieve()
.asIterator(getApiRoute() + "/comments",
GHPullRequestReviewComment[].class, pageSize)) {
protected void wrapUp(GHPullRequestReviewComment[] page) {
for (GHPullRequestReviewComment c : page)
c.wrapUp(owner);
}
};
}
};
return owner.root.retrieve()
.asPagedIterable(getApiRoute() + "/comments",
GHPullRequestReviewComment[].class,
item -> item.wrapUp(owner));
}
}

View File

@@ -8,59 +8,89 @@ import java.util.List;
* Builds up a creation of new {@link GHPullRequestReview}.
*
* @author Kohsuke Kawaguchi
* @see GHPullRequest#createReview()
* @see GHPullRequest#createReview() GHPullRequest#createReview()
*/
public class GHPullRequestReviewBuilder {
private final GHPullRequest pr;
private final Requester builder;
private final List<DraftReviewComment> comments = new ArrayList<DraftReviewComment>();
/*package*/ GHPullRequestReviewBuilder(GHPullRequest pr) {
GHPullRequestReviewBuilder(GHPullRequest pr) {
this.pr = pr;
this.builder = new Requester(pr.root);
}
// public GHPullRequestReview createReview(@Nullable String commitId, String body, GHPullRequestReviewEvent event,
// List<GHPullRequestReviewComment> comments) throws IOException
// public GHPullRequestReview createReview(@Nullable String commitId, String body, GHPullRequestReviewEvent event,
// List<GHPullRequestReviewComment> comments) throws IOException
/**
* The SHA of the commit that needs a review. Not using the latest commit SHA may render your review comment outdated if a subsequent commit modifies the line you specify as the position. Defaults to the most recent commit in the pull request when you do not specify a value.
* The SHA of the commit that needs a review. Not using the latest commit SHA may render your review comment
* outdated if a subsequent commit modifies the line you specify as the position. Defaults to the most recent commit
* in the pull request when you do not specify a value.
*
* @param commitId
* the commit id
* @return the gh pull request review builder
*/
public GHPullRequestReviewBuilder commitId(String commitId) {
builder.with("commit_id",commitId);
builder.with("commit_id", commitId);
return this;
}
/**
* Required when using REQUEST_CHANGES or COMMENT for the event parameter. The body text of the pull request review.
*
* @param body
* the body
* @return the gh pull request review builder
*/
public GHPullRequestReviewBuilder body(String body) {
builder.with("body",body);
builder.with("body", body);
return this;
}
/**
* The review action you want to perform. The review actions include: APPROVE, REQUEST_CHANGES, or COMMENT.
* By leaving this blank, you set the review action state to PENDING,
* which means you will need to {@linkplain GHPullRequestReview#submit(String, GHPullRequestReviewEvent) submit the pull request review} when you are ready.
* The review action you want to perform. The review actions include: APPROVE, REQUEST_CHANGES, or COMMENT. By
* leaving this blank, you set the review action state to PENDING, which means you will need to
* {@linkplain GHPullRequestReview#submit(String, GHPullRequestReviewEvent) submit the pull request review} when you
* are ready.
*
* @param event
* the event
* @return the gh pull request review builder
*/
public GHPullRequestReviewBuilder event(GHPullRequestReviewEvent event) {
builder.with("event",event.action());
builder.with("event", event.action());
return this;
}
/**
* @param body The relative path to the file that necessitates a review comment.
* @param path The position in the diff where you want to add a review comment. Note this value is not the same as the line number in the file. For help finding the position value, read the note below.
* @param position Text of the review comment.
* Comment gh pull request review builder.
*
* @param body
* The relative path to the file that necessitates a review comment.
* @param path
* The position in the diff where you want to add a review comment. Note this value is not the same as
* the line number in the file. For help finding the position value, read the note below.
* @param position
* Text of the review comment.
* @return the gh pull request review builder
*/
public GHPullRequestReviewBuilder comment(String body, String path, int position) {
comments.add(new DraftReviewComment(body,path,position));
comments.add(new DraftReviewComment(body, path, position));
return this;
}
/**
* Create gh pull request review.
*
* @return the gh pull request review
* @throws IOException
* the io exception
*/
public GHPullRequestReview create() throws IOException {
return builder.method("POST")._with("comments",comments)
return builder.method("POST")
.with("comments", comments)
.to(pr.getApiRoute() + "/reviews", GHPullRequestReview.class)
.wrapUp(pr);
}
@@ -76,14 +106,29 @@ public class GHPullRequestReviewBuilder {
this.position = position;
}
/**
* Gets body.
*
* @return the body
*/
public String getBody() {
return body;
}
/**
* Gets path.
*
* @return the path
*/
public String getPath() {
return path;
}
/**
* Gets position.
*
* @return the position
*/
public int getPosition() {
return position;
}

View File

@@ -25,6 +25,7 @@ package org.kohsuke.github;
import java.io.IOException;
import java.net.URL;
import javax.annotation.CheckForNull;
import static org.kohsuke.github.Previews.*;
@@ -33,8 +34,9 @@ import static org.kohsuke.github.Previews.*;
* Review comment to the pull request
*
* @author Julien Henry
* @see GHPullRequest#listReviewComments()
* @see GHPullRequest#createReviewComment(String, String, String, int)
* @see GHPullRequest#listReviewComments() GHPullRequest#listReviewComments()
* @see GHPullRequest#createReviewComment(String, String, String, int) GHPullRequest#createReviewComment(String, String,
* String, int)
*/
public class GHPullRequestReviewComment extends GHObject implements Reactable {
GHPullRequest owner;
@@ -46,10 +48,17 @@ public class GHPullRequestReviewComment extends GHObject implements Reactable {
private int original_position = -1;
private long in_reply_to_id = -1L;
/**
* @deprecated
* You should be using {@link GHPullRequestReviewBuilder#comment(String, String, int)}
* Draft gh pull request review comment.
*
* @param body
* the body
* @param path
* the path
* @param position
* the position
* @return the gh pull request review comment
* @deprecated You should be using {@link GHPullRequestReviewBuilder#comment(String, String, int)}
*/
public static GHPullRequestReviewComment draft(String body, String path, int position) {
GHPullRequestReviewComment result = new GHPullRequestReviewComment();
@@ -59,13 +68,15 @@ public class GHPullRequestReviewComment extends GHObject implements Reactable {
return result;
}
/*package*/ GHPullRequestReviewComment wrapUp(GHPullRequest owner) {
GHPullRequestReviewComment wrapUp(GHPullRequest owner) {
this.owner = owner;
return this;
}
/**
* Gets the pull request to which this review comment is associated.
*
* @return the parent
*/
public GHPullRequest getParent() {
return owner;
@@ -73,6 +84,8 @@ public class GHPullRequestReviewComment extends GHObject implements Reactable {
/**
* The comment itself.
*
* @return the body
*/
public String getBody() {
return body;
@@ -80,24 +93,48 @@ public class GHPullRequestReviewComment extends GHObject implements Reactable {
/**
* Gets the user who posted this comment.
*
* @return the user
* @throws IOException
* the io exception
*/
public GHUser getUser() throws IOException {
return owner.root.getUser(user.getLogin());
}
/**
* Gets path.
*
* @return the path
*/
public String getPath() {
return path;
}
/**
* Gets position.
*
* @return the position
*/
@CheckForNull
public int getPosition() {
return position;
}
/**
* Gets original position.
*
* @return the original position
*/
public int getOriginalPosition() {
return original_position;
}
/**
* Gets in reply to id.
*
* @return the in reply to id
*/
@CheckForNull
public long getInReplyToId() {
return in_reply_to_id;
@@ -108,20 +145,33 @@ public class GHPullRequestReviewComment extends GHObject implements Reactable {
return null;
}
/**
* Gets api route.
*
* @return the api route
*/
protected String getApiRoute() {
return "/repos/"+owner.getRepository().getFullName()+"/pulls/comments/"+id;
return "/repos/" + owner.getRepository().getFullName() + "/pulls/comments/" + id;
}
/**
* Updates the comment.
*
* @param body
* the body
* @throws IOException
* the io exception
*/
public void update(String body) throws IOException {
new Requester(owner.root).method("PATCH").with("body", body).to(getApiRoute(),this);
new Requester(owner.root).method("PATCH").with("body", body).to(getApiRoute(), this);
this.body = body;
}
/**
* Deletes this review comment.
*
* @throws IOException
* the io exception
*/
public void delete() throws IOException {
new Requester(owner.root).method("DELETE").to(getApiRoute());
@@ -129,6 +179,12 @@ public class GHPullRequestReviewComment extends GHObject implements Reactable {
/**
* Create a new comment that replies to this comment.
*
* @param body
* the body
* @return the gh pull request review comment
* @throws IOException
* the io exception
*/
public GHPullRequestReviewComment reply(String body) throws IOException {
return new Requester(owner.root).method("POST")
@@ -138,26 +194,20 @@ public class GHPullRequestReviewComment extends GHObject implements Reactable {
.wrapUp(owner);
}
@Preview @Deprecated
@Preview
@Deprecated
public GHReaction createReaction(ReactionContent content) throws IOException {
return new Requester(owner.root)
.withPreview(SQUIRREL_GIRL)
return new Requester(owner.root).withPreview(SQUIRREL_GIRL)
.with("content", content.getContent())
.to(getApiRoute()+"/reactions", GHReaction.class).wrap(owner.root);
.to(getApiRoute() + "/reactions", GHReaction.class)
.wrap(owner.root);
}
@Preview @Deprecated
@Preview
@Deprecated
public PagedIterable<GHReaction> listReactions() {
return new PagedIterable<GHReaction>() {
public PagedIterator<GHReaction> _iterator(int pageSize) {
return new PagedIterator<GHReaction>(owner.root.retrieve().withPreview(SQUIRREL_GIRL).asIterator(getApiRoute() + "/reactions", GHReaction[].class, pageSize)) {
@Override
protected void wrapUp(GHReaction[] page) {
for (GHReaction c : page)
c.wrap(owner.root);
}
};
}
};
return owner.root.retrieve()
.withPreview(SQUIRREL_GIRL)
.asPagedIterable(getApiRoute() + "/reactions", GHReaction[].class, item -> item.wrap(owner.root));
}
}

View File

@@ -27,24 +27,25 @@ package org.kohsuke.github;
* Action to perform on {@link GHPullRequestReview}.
*/
public enum GHPullRequestReviewEvent {
PENDING,
APPROVE,
REQUEST_CHANGES,
COMMENT;
PENDING, APPROVE, REQUEST_CHANGES, COMMENT;
/*package*/ String action() {
return this==PENDING ? null : name();
String action() {
return this == PENDING ? null : name();
}
/**
* When a {@link GHPullRequestReview} is submitted with this event, it should transition to this state.
*/
/*package*/ GHPullRequestReviewState toState() {
GHPullRequestReviewState toState() {
switch (this) {
case PENDING: return GHPullRequestReviewState.PENDING;
case APPROVE: return GHPullRequestReviewState.APPROVED;
case REQUEST_CHANGES: return GHPullRequestReviewState.CHANGES_REQUESTED;
case COMMENT: return GHPullRequestReviewState.COMMENTED;
case PENDING :
return GHPullRequestReviewState.PENDING;
case APPROVE :
return GHPullRequestReviewState.APPROVED;
case REQUEST_CHANGES :
return GHPullRequestReviewState.CHANGES_REQUESTED;
case COMMENT :
return GHPullRequestReviewState.COMMENTED;
}
throw new IllegalStateException();
}

View File

@@ -8,31 +8,36 @@ public enum GHPullRequestReviewState {
APPROVED,
CHANGES_REQUESTED,
/**
* @deprecated
* This was the thing when this API was in preview, but it changed when it became public.
* Use {@link #CHANGES_REQUESTED}. Left here for compatibility.
* @deprecated This was the thing when this API was in preview, but it changed when it became public. Use
* {@link #CHANGES_REQUESTED}. Left here for compatibility.
*/
REQUEST_CHANGES,
COMMENTED,
DISMISSED;
/**
* @deprecated
* This was an internal method accidentally exposed.
* Left here for compatibility.
* Action string.
*
* @return the string
* @deprecated This was an internal method accidentally exposed. Left here for compatibility.
*/
public String action() {
GHPullRequestReviewEvent e = toEvent();
return e==null ? null : e.action();
return e == null ? null : e.action();
}
/*package*/ GHPullRequestReviewEvent toEvent() {
GHPullRequestReviewEvent toEvent() {
switch (this) {
case PENDING: return GHPullRequestReviewEvent.PENDING;
case APPROVED: return GHPullRequestReviewEvent.APPROVE;
case CHANGES_REQUESTED: return GHPullRequestReviewEvent.REQUEST_CHANGES;
case REQUEST_CHANGES: return GHPullRequestReviewEvent.REQUEST_CHANGES;
case COMMENTED: return GHPullRequestReviewEvent.COMMENT;
case PENDING :
return GHPullRequestReviewEvent.PENDING;
case APPROVED :
return GHPullRequestReviewEvent.APPROVE;
case CHANGES_REQUESTED :
return GHPullRequestReviewEvent.REQUEST_CHANGES;
case REQUEST_CHANGES :
return GHPullRequestReviewEvent.REQUEST_CHANGES;
case COMMENTED :
return GHPullRequestReviewEvent.COMMENT;
}
return null;
}

View File

@@ -3,19 +3,23 @@ package org.kohsuke.github;
/**
* Used to specify filters, sort order, etc for listing items in a collection.
*
* @param <T>
* the type parameter
* @author Kohsuke Kawaguchi
*/
public abstract class GHQueryBuilder<T> {
protected final GitHub root;
protected final Requester req;
/*package*/ GHQueryBuilder(GitHub root) {
GHQueryBuilder(GitHub root) {
this.root = root;
this.req = root.retrieve();
}
/**
* Start listing items by using the settings built up on this object.
*
* @return the paged iterable
*/
public abstract PagedIterable<T> list();
}

View File

@@ -1,43 +1,400 @@
package org.kohsuke.github;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import org.apache.commons.lang3.StringUtils;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.Date;
import java.util.Objects;
import java.util.logging.Logger;
import javax.annotation.Nonnull;
import static java.util.logging.Level.FINEST;
/**
* Rate limit.
*
* @author Kohsuke Kawaguchi
*/
@SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD", justification = "JSON API")
public class GHRateLimit {
/**
* Remaining calls that can be made.
*
* @deprecated This value should never have been made public. Use {@link #getRemaining()}
*/
@Deprecated
public int remaining;
/**
* Allotted API call per hour.
*
* @deprecated This value should never have been made public. Use {@link #getLimit()}
*/
@Deprecated
public int limit;
/**
* The time at which the current rate limit window resets in UTC epoch seconds.
* The time at which the current rate limit window resets in UTC epoch seconds. NOTE: that means to
*
* @deprecated This value should never have been made public. Use {@link #getResetDate()}
*/
@Deprecated
public Date reset;
@Nonnull
private final Record core;
@Nonnull
private final Record search;
@Nonnull
private final Record graphql;
@Nonnull
private final Record integrationManifest;
static GHRateLimit Unknown() {
return new GHRateLimit(new UnknownLimitRecord(),
new UnknownLimitRecord(),
new UnknownLimitRecord(),
new UnknownLimitRecord());
}
static GHRateLimit fromHeaderRecord(Record header) {
return new GHRateLimit(header, new UnknownLimitRecord(), new UnknownLimitRecord(), new UnknownLimitRecord());
}
@JsonCreator
GHRateLimit(@Nonnull @JsonProperty("core") Record core,
@Nonnull @JsonProperty("search") Record search,
@Nonnull @JsonProperty("graphql") Record graphql,
@Nonnull @JsonProperty("integration_manifest") Record integrationManifest) {
this.core = core;
this.search = search;
this.graphql = graphql;
this.integrationManifest = integrationManifest;
// Deprecated fields
this.remaining = core.getRemaining();
this.limit = core.getLimit();
this.reset = new Date(core.getResetEpochSeconds());
}
/**
* Non-epoch date
* Returns the date at which the Core API rate limit will reset.
*
* @return the calculated date at which the rate limit has or will reset.
*/
@SuppressFBWarnings(value = "UWF_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR",
justification = "The value comes from JSON deserialization")
@Nonnull
public Date getResetDate() {
return new Date(reset.getTime() * 1000);
return getCore().getResetDate();
}
/**
* Gets the remaining number of Core APIs requests allowed before this connection will be throttled.
*
* @return an integer
* @since 1.100
*/
public int getRemaining() {
return getCore().getRemaining();
}
/**
* Gets the total number of Core API calls per hour allotted for this connection.
*
* @return an integer
* @since 1.100
*/
public int getLimit() {
return getCore().getLimit();
}
/**
* Gets the time in epoch seconds when the Core API rate limit will reset.
*
* @return a long
* @since 1.100
*/
public long getResetEpochSeconds() {
return getCore().getResetEpochSeconds();
}
/**
* Whether the rate limit reset date for this instance has passed.
*
* @return true if the rate limit reset date has passed. Otherwise false.
* @since 1.100
*/
public boolean isExpired() {
return getCore().isExpired();
}
/**
* The core object provides your rate limit status for all non-search-related resources in the REST API.
*
* @return a rate limit record
* @since 1.100
*/
@Nonnull
public Record getCore() {
return core;
}
/**
* The search object provides your rate limit status for the Search API. TODO: integrate with header limit updating.
* Issue #605.
*
* @return a rate limit record
*/
@Nonnull
Record getSearch() {
return search;
}
/**
* The graphql object provides your rate limit status for the GraphQL API. TODO: integrate with header limit
* updating. Issue #605.
*
* @return a rate limit record
*/
@Nonnull
Record getGraphQL() {
return graphql;
}
/**
* The integration_manifest object provides your rate limit status for the GitHub App Manifest code conversion
* endpoint. TODO: integrate with header limit updating. Issue #605.
*
* @return a rate limit record
*/
@Nonnull
Record getIntegrationManifest() {
return integrationManifest;
}
@Override
public String toString() {
return "GHRateLimit{" +
"remaining=" + remaining +
", limit=" + limit +
", resetDate=" + getResetDate() +
'}';
return "GHRateLimit {" + "core " + getCore().toString() + "search " + getSearch().toString() + "graphql "
+ getGraphQL().toString() + "integrationManifest " + getIntegrationManifest().toString() + '}';
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
GHRateLimit rateLimit = (GHRateLimit) o;
return getCore().equals(rateLimit.getCore()) && getSearch().equals(rateLimit.getSearch())
&& getGraphQL().equals(rateLimit.getGraphQL())
&& getIntegrationManifest().equals(rateLimit.getIntegrationManifest());
}
@Override
public int hashCode() {
return Objects.hash(getCore(), getSearch(), getGraphQL(), getIntegrationManifest());
}
/**
* A limit record used as a placeholder when the the actual limit is not known.
* <p>
* Has a large limit and long duration so that it will doesn't expire too often.
*
* @since 1.100
*/
public static class UnknownLimitRecord extends Record {
// One hour
private static final long unknownLimitResetSeconds = 60L * 60L;
static final int unknownLimit = 1000000;
static final int unknownRemaining = 999999;
private UnknownLimitRecord() {
super(unknownLimit, unknownRemaining, System.currentTimeMillis() / 1000L + unknownLimitResetSeconds);
}
}
/**
* A rate limit record.
*
* @since 1.100
*/
public static class Record {
/**
* Remaining calls that can be made.
*/
private final int remaining;
/**
* Allotted API call per hour.
*/
private final int limit;
/**
* The time at which the current rate limit window resets in UTC epoch seconds.
*/
private final long resetEpochSeconds;
/**
* EpochSeconds time (UTC) at which this instance was created.
*/
private final long createdAtEpochSeconds = System.currentTimeMillis() / 1000;
/**
* The calculated time at which the rate limit will reset. Recalculated if {@link #recalculateResetDate} is
* called.
*/
@Nonnull
private Date resetDate;
/**
* Instantiates a new Record.
*
* @param limit
* the limit
* @param remaining
* the remaining
* @param resetEpochSeconds
* the reset epoch seconds
*/
@JsonCreator
public Record(@JsonProperty("limit") int limit,
@JsonProperty("remaining") int remaining,
@JsonProperty("reset") long resetEpochSeconds) {
this(limit, remaining, resetEpochSeconds, null);
}
/**
* Instantiates a new Record.
*
* @param limit
* the limit
* @param remaining
* the remaining
* @param resetEpochSeconds
* the reset epoch seconds
* @param updatedAt
* the updated at
*/
@SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD", justification = "Deprecated")
public Record(int limit, int remaining, long resetEpochSeconds, String updatedAt) {
this.limit = limit;
this.remaining = remaining;
this.resetEpochSeconds = resetEpochSeconds;
this.resetDate = recalculateResetDate(updatedAt);
}
/**
* Recalculates the reset date using the server response date to calculate a time duration and then add that to
* the local created time for this record.
*
* @param updatedAt
* a string date in RFC 1123
* @return reset date based on the passed date
*/
Date recalculateResetDate(String updatedAt) {
long updatedAtEpochSeconds = createdAtEpochSeconds;
if (!StringUtils.isBlank(updatedAt)) {
try {
// Get the server date and reset data, will always return a time in GMT
updatedAtEpochSeconds = ZonedDateTime.parse(updatedAt, DateTimeFormatter.RFC_1123_DATE_TIME)
.toEpochSecond();
} catch (DateTimeParseException e) {
if (LOGGER.isLoggable(FINEST)) {
LOGGER.log(FINEST, "Malformed Date header value " + updatedAt, e);
}
}
}
// This may seem odd but it results in an accurate or slightly pessimistic reset date
// based on system time rather than on the system being in sync with the server
long calculatedSecondsUntilReset = resetEpochSeconds - updatedAtEpochSeconds;
return resetDate = new Date((createdAtEpochSeconds + calculatedSecondsUntilReset) * 1000);
}
/**
* Gets the remaining number of requests allowed before this connection will be throttled.
*
* @return an integer
*/
public int getRemaining() {
return remaining;
}
/**
* Gets the total number of API calls per hour allotted for this connection.
*
* @return an integer
*/
public int getLimit() {
return limit;
}
/**
* Gets the time in epoch seconds when the rate limit will reset.
*
* @return a long
*/
public long getResetEpochSeconds() {
return resetEpochSeconds;
}
/**
* Whether the rate limit reset date indicated by this instance is in the
*
* @return true if the rate limit reset date has passed. Otherwise false.
*/
public boolean isExpired() {
return getResetDate().getTime() < System.currentTimeMillis();
}
/**
* Returns the date at which the rate limit will reset.
*
* @return the calculated date at which the rate limit has or will reset.
*/
@Nonnull
public Date getResetDate() {
return new Date(resetDate.getTime());
}
@Override
public String toString() {
return "{" + "remaining=" + getRemaining() + ", limit=" + getLimit() + ", resetDate=" + getResetDate()
+ '}';
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Record record = (Record) o;
return getRemaining() == record.getRemaining() && getLimit() == record.getLimit()
&& getResetEpochSeconds() == record.getResetEpochSeconds()
&& getResetDate().equals(record.getResetDate());
}
@Override
public int hashCode() {
return Objects.hash(getRemaining(), getLimit(), getResetEpochSeconds(), getResetDate());
}
}
private static final Logger LOGGER = Logger.getLogger(Requester.class.getName());
}

View File

@@ -11,14 +11,15 @@ import static org.kohsuke.github.Previews.*;
* @author Kohsuke Kawaguchi
* @see Reactable
*/
@Preview @Deprecated
@Preview
@Deprecated
public class GHReaction extends GHObject {
private GitHub root;
private GHUser user;
private ReactionContent content;
/*package*/ GHReaction wrap(GitHub root) {
GHReaction wrap(GitHub root) {
this.root = root;
user.wrapUp(root);
return this;
@@ -26,6 +27,8 @@ public class GHReaction extends GHObject {
/**
* The kind of reaction left.
*
* @return the content
*/
public ReactionContent getContent() {
return content;
@@ -33,6 +36,8 @@ public class GHReaction extends GHObject {
/**
* User who left the reaction.
*
* @return the user
*/
public GHUser getUser() {
return user;
@@ -48,8 +53,11 @@ public class GHReaction extends GHObject {
/**
* Removes this reaction.
*
* @throws IOException
* the io exception
*/
public void delete() throws IOException {
new Requester(root).method("DELETE").withPreview(SQUIRREL_GIRL).to("/reactions/"+id);
new Requester(root).method("DELETE").withPreview(SQUIRREL_GIRL).to("/reactions/" + id);
}
}

View File

@@ -11,13 +11,15 @@ import java.net.URL;
* @author Michael Clarke
*/
public class GHRef {
/*package almost final*/ GitHub root;
/* package almost final */ GitHub root;
private String ref, url;
private GHObject object;
/**
* Name of the ref, such as "refs/tags/abc"
*
* @return the ref
*/
public String getRef() {
return ref;
@@ -25,6 +27,8 @@ public class GHRef {
/**
* The API URL of this tag, such as https://api.github.com/repos/jenkinsci/jenkins/git/refs/tags/1.312
*
* @return the url
*/
public URL getUrl() {
return GitHub.parseURL(url);
@@ -32,6 +36,8 @@ public class GHRef {
/**
* The object that this ref points to.
*
* @return the object
*/
public GHObject getObject() {
return object;
@@ -41,51 +47,63 @@ public class GHRef {
* Updates this ref to the specified commit.
*
* @param sha
* The SHA1 value to set this reference to
* The SHA1 value to set this reference to
* @throws IOException
* the io exception
*/
public void updateTo(String sha) throws IOException {
updateTo(sha, false);
updateTo(sha, false);
}
/**
* Updates this ref to the specified commit.
*
* @param sha
* The SHA1 value to set this reference to
* The SHA1 value to set this reference to
* @param force
* Whether or not to force this ref update.
* Whether or not to force this ref update.
* @throws IOException
* the io exception
*/
public void updateTo(String sha, Boolean force) throws IOException {
new Requester(root)
.with("sha", sha).with("force", force).method("PATCH").to(url, GHRef.class).wrap(root);
new Requester(root).with("sha", sha).with("force", force).method("PATCH").to(url, GHRef.class).wrap(root);
}
/**
* Deletes this ref from the repository using the GitHub API.
*
* @throws IOException
* the io exception
*/
public void delete() throws IOException {
new Requester(root).method("DELETE").to(url);
new Requester(root).method("DELETE").to(url);
}
/*package*/ GHRef wrap(GitHub root) {
GHRef wrap(GitHub root) {
this.root = root;
return this;
}
/*package*/ static GHRef[] wrap(GHRef[] in, GitHub root) {
static GHRef[] wrap(GHRef[] in, GitHub root) {
for (GHRef r : in) {
r.wrap(root);
}
return in;
}
@SuppressFBWarnings(value = {"UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD",
"NP_UNWRITTEN_FIELD"}, justification = "JSON API")
/**
* The type GHObject.
*/
@SuppressFBWarnings(
value = { "UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD", "NP_UNWRITTEN_FIELD" },
justification = "JSON API")
public static class GHObject {
private String type, sha, url;
private String type, sha, url;
/**
* Type of the object, such as "commit"
*
* @return the type
*/
public String getType() {
return type;
@@ -93,13 +111,18 @@ public class GHRef {
/**
* SHA1 of this object.
*
* @return the sha
*/
public String getSha() {
return sha;
}
/**
* API URL to this Git data, such as https://api.github.com/repos/jenkinsci/jenkins/git/commits/b72322675eb0114363a9a86e9ad5a170d1d07ac0
* API URL to this Git data, such as
* https://api.github.com/repos/jenkinsci/jenkins/git/commits/b72322675eb0114363a9a86e9ad5a170d1d07ac0
*
* @return the url
*/
public URL getUrl() {
return GitHub.parseURL(url);

View File

@@ -3,7 +3,9 @@ package org.kohsuke.github;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
@@ -13,8 +15,8 @@ import static java.lang.String.*;
/**
* Release in a github repository.
*
* @see GHRepository#getReleases()
* @see GHRepository#createRelease(String)
* @see GHRepository#getReleases() GHRepository#getReleases()
* @see GHRepository#createRelease(String) GHRepository#createRelease(String)
*/
public class GHRelease extends GHObject {
GitHub root;
@@ -33,21 +35,42 @@ public class GHRelease extends GHObject {
private String tarball_url;
private String zipball_url;
/**
* Gets assets url.
*
* @return the assets url
*/
public String getAssetsUrl() {
return assets_url;
}
/**
* Gets body.
*
* @return the body
*/
public String getBody() {
return body;
}
/**
* Is draft boolean.
*
* @return the boolean
*/
public boolean isDraft() {
return draft;
}
/**
* @deprecated
* Use {@link #update()}
* Sets draft.
*
* @param draft
* the draft
* @return the draft
* @throws IOException
* the io exception
* @deprecated Use {@link #update()}
*/
public GHRelease setDraft(boolean draft) throws IOException {
return update().draft(draft).update();
@@ -57,50 +80,112 @@ public class GHRelease extends GHObject {
return GitHub.parseURL(html_url);
}
/**
* Gets name.
*
* @return the name
*/
public String getName() {
return name;
}
/**
* Sets name.
*
* @param name
* the name
*/
public void setName(String name) {
this.name = name;
}
/**
* Gets owner.
*
* @return the owner
*/
public GHRepository getOwner() {
return owner;
}
/**
* Sets owner.
*
* @param owner
* the owner
*/
public void setOwner(GHRepository owner) {
this.owner = owner;
}
/**
* Is prerelease boolean.
*
* @return the boolean
*/
public boolean isPrerelease() {
return prerelease;
}
/**
* Gets published at.
*
* @return the published at
*/
public Date getPublished_at() {
return new Date(published_at.getTime());
}
/**
* Gets root.
*
* @return the root
*/
public GitHub getRoot() {
return root;
}
/**
* Gets tag name.
*
* @return the tag name
*/
public String getTagName() {
return tag_name;
}
/**
* Gets target commitish.
*
* @return the target commitish
*/
public String getTargetCommitish() {
return target_commitish;
}
/**
* Gets upload url.
*
* @return the upload url
*/
public String getUploadUrl() {
return upload_url;
}
/**
* Gets zipball url.
*
* @return the zipball url
*/
public String getZipballUrl() {
return zipball_url;
}
/**
* Gets tarball url.
*
* @return the tarball url
*/
public String getTarballUrl() {
return tarball_url;
}
@@ -120,44 +205,83 @@ public class GHRelease extends GHObject {
/**
* Because github relies on SNI (http://en.wikipedia.org/wiki/Server_Name_Indication) this method will only work on
* Java 7 or greater. Options for fixing this for earlier JVMs can be found here
* Java 7 or greater. Options for fixing this for earlier JVMs can be found here
* http://stackoverflow.com/questions/12361090/server-name-indication-sni-on-java but involve more complicated
* handling of the HTTP requests to github's API.
*/
*
* @param file
* the file
* @param contentType
* the content type
* @return the gh asset
* @throws IOException
* the io exception
*/
public GHAsset uploadAsset(File file, String contentType) throws IOException {
Requester builder = new Requester(owner.root);
String url = format("https://uploads.github.com%s/releases/%d/assets?name=%s",
owner.getApiTailUrl(""), getId(), file.getName());
return builder.contentType(contentType)
.with(new FileInputStream(file))
.to(url, GHAsset.class).wrap(this);
FileInputStream s = new FileInputStream(file);
try {
return uploadAsset(file.getName(), s, contentType);
} finally {
s.close();
}
}
/**
* Upload asset gh asset.
*
* @param filename
* the filename
* @param stream
* the stream
* @param contentType
* the content type
* @return the gh asset
* @throws IOException
* the io exception
*/
public GHAsset uploadAsset(String filename, InputStream stream, String contentType) throws IOException {
Requester builder = new Requester(owner.root);
String url = getUploadUrl();
// strip the helpful garbage from the url
url = url.substring(0, url.indexOf('{'));
url += "?name=" + URLEncoder.encode(filename, "UTF-8");
return builder.contentType(contentType).with(stream).to(url, GHAsset.class).wrap(this);
}
/**
* Gets assets.
*
* @return the assets
* @throws IOException
* the io exception
*/
public List<GHAsset> getAssets() throws IOException {
Requester builder = new Requester(owner.root);
GHAsset[] assets = builder
.method("GET")
.to(getApiTailUrl("assets"), GHAsset[].class);
GHAsset[] assets = builder.method("GET").to(getApiTailUrl("assets"), GHAsset[].class);
return Arrays.asList(GHAsset.wrap(assets, this));
}
/**
* Deletes this release.
*
* @throws IOException
* the io exception
*/
public void delete() throws IOException {
new Requester(root).method("DELETE").to(owner.getApiTailUrl("releases/"+id));
new Requester(root).method("DELETE").to(owner.getApiTailUrl("releases/" + id));
}
/**
* Updates this release via a builder.
*
* @return the gh release updater
*/
public GHReleaseUpdater update() {
return new GHReleaseUpdater(this);
}
private String getApiTailUrl(String end) {
return owner.getApiTailUrl(format("releases/%s/%s",id,end));
return owner.getApiTailUrl(format("releases/%s/%s", id, end));
}
}

View File

@@ -5,12 +5,20 @@ import java.io.IOException;
/**
* Builder pattern for creating a {@link GHRelease}
*
* @see GHRepository#createRelease(String)
* @see GHRepository#createRelease(String) GHRepository#createRelease(String)
*/
public class GHReleaseBuilder {
private final GHRepository repo;
private final Requester builder;
/**
* Instantiates a new Gh release builder.
*
* @param ghRepository
* the gh repository
* @param tag
* the tag
*/
public GHReleaseBuilder(GHRepository ghRepository, String tag) {
this.repo = ghRepository;
this.builder = new Requester(repo.root);
@@ -18,7 +26,11 @@ public class GHReleaseBuilder {
}
/**
* @param body The release notes body.
* Body gh release builder.
*
* @param body
* The release notes body.
* @return the gh release builder
*/
public GHReleaseBuilder body(String body) {
builder.with("body", body);
@@ -26,11 +38,11 @@ public class GHReleaseBuilder {
}
/**
* Specifies the commitish value that determines where the Git tag is created from. Can be any branch or
* commit SHA.
* Specifies the commitish value that determines where the Git tag is created from. Can be any branch or commit SHA.
*
* @param commitish Defaults to the repositorys default branch (usually "master"). Unused if the Git tag
* already exists.
* @param commitish
* Defaults to the repositorys default branch (usually "master"). Unused if the Git tag already exists.
* @return the gh release builder
*/
public GHReleaseBuilder commitish(String commitish) {
builder.with("target_commitish", commitish);
@@ -40,8 +52,10 @@ public class GHReleaseBuilder {
/**
* Optional.
*
* @param draft {@code true} to create a draft (unpublished) release, {@code false} to create a published one.
* Default is {@code false}.
* @param draft
* {@code true} to create a draft (unpublished) release, {@code false} to create a published one. Default
* is {@code false}.
* @return the gh release builder
*/
public GHReleaseBuilder draft(boolean draft) {
builder.with("draft", draft);
@@ -49,7 +63,11 @@ public class GHReleaseBuilder {
}
/**
* @param name the name of the release
* Name gh release builder.
*
* @param name
* the name of the release
* @return the gh release builder
*/
public GHReleaseBuilder name(String name) {
builder.with("name", name);
@@ -59,14 +77,23 @@ public class GHReleaseBuilder {
/**
* Optional
*
* @param prerelease {@code true} to identify the release as a prerelease. {@code false} to identify the release
* as a full release. Default is {@code false}.
* @param prerelease
* {@code true} to identify the release as a prerelease. {@code false} to identify the release as a full
* release. Default is {@code false}.
* @return the gh release builder
*/
public GHReleaseBuilder prerelease(boolean prerelease) {
builder.with("prerelease", prerelease);
return this;
}
/**
* Create gh release.
*
* @return the gh release
* @throws IOException
* the io exception
*/
public GHRelease create() throws IOException {
return builder.to(repo.getApiTailUrl("releases"), GHRelease.class).wrap(repo);
}

View File

@@ -6,7 +6,7 @@ import java.io.IOException;
* Modifies {@link GHRelease}.
*
* @author Kohsuke Kawaguchi
* @see GHRelease#update()
* @see GHRelease#update() GHRelease#update()
*/
public class GHReleaseUpdater {
private final GHRelease base;
@@ -17,13 +17,24 @@ public class GHReleaseUpdater {
this.builder = new Requester(base.root);
}
/**
* Tag gh release updater.
*
* @param tag
* the tag
* @return the gh release updater
*/
public GHReleaseUpdater tag(String tag) {
builder.with("tag_name",tag);
builder.with("tag_name", tag);
return this;
}
/**
* @param body The release notes body.
* Body gh release updater.
*
* @param body
* The release notes body.
* @return the gh release updater
*/
public GHReleaseUpdater body(String body) {
builder.with("body", body);
@@ -31,11 +42,11 @@ public class GHReleaseUpdater {
}
/**
* Specifies the commitish value that determines where the Git tag is created from. Can be any branch or
* commit SHA.
* Specifies the commitish value that determines where the Git tag is created from. Can be any branch or commit SHA.
*
* @param commitish Defaults to the repositorys default branch (usually "master"). Unused if the Git tag
* already exists.
* @param commitish
* Defaults to the repositorys default branch (usually "master"). Unused if the Git tag already exists.
* @return the gh release updater
*/
public GHReleaseUpdater commitish(String commitish) {
builder.with("target_commitish", commitish);
@@ -45,8 +56,10 @@ public class GHReleaseUpdater {
/**
* Optional.
*
* @param draft {@code true} to create a draft (unpublished) release, {@code false} to create a published one.
* Default is {@code false}.
* @param draft
* {@code true} to create a draft (unpublished) release, {@code false} to create a published one. Default
* is {@code false}.
* @return the gh release updater
*/
public GHReleaseUpdater draft(boolean draft) {
builder.with("draft", draft);
@@ -54,7 +67,11 @@ public class GHReleaseUpdater {
}
/**
* @param name the name of the release
* Name gh release updater.
*
* @param name
* the name of the release
* @return the gh release updater
*/
public GHReleaseUpdater name(String name) {
builder.with("name", name);
@@ -64,18 +81,27 @@ public class GHReleaseUpdater {
/**
* Optional
*
* @param prerelease {@code true} to identify the release as a prerelease. {@code false} to identify the release
* as a full release. Default is {@code false}.
* @param prerelease
* {@code true} to identify the release as a prerelease. {@code false} to identify the release as a full
* release. Default is {@code false}.
* @return the gh release updater
*/
public GHReleaseUpdater prerelease(boolean prerelease) {
builder.with("prerelease", prerelease);
return this;
}
/**
* Update gh release.
*
* @return the gh release
* @throws IOException
* the io exception
*/
public GHRelease update() throws IOException {
return builder
.method("PATCH")
.to(base.owner.getApiTailUrl("releases/"+base.id), GHRelease.class).wrap(base.owner);
return builder.method("PATCH")
.to(base.owner.getApiTailUrl("releases/" + base.id), GHRelease.class)
.wrap(base.owner);
}
}

View File

@@ -4,9 +4,9 @@ class GHRepoHook extends GHHook {
/**
* Repository that the hook belongs to.
*/
/*package*/ transient GHRepository repository;
transient GHRepository repository;
/*package*/ GHRepoHook wrap(GHRepository owner) {
GHRepoHook wrap(GHRepository owner) {
this.repository = owner;
return this;
}

Some files were not shown because too many files have changed in this diff Show More