mirror of
https://github.com/jlengrand/github-api.git
synced 2026-03-11 08:21:23 +00:00
Compare commits
1889 Commits
github-api
...
github-api
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a7a792251a | ||
|
|
aec2308144 | ||
|
|
0741b8aa6a | ||
|
|
3082622394 | ||
|
|
965c9cb0af | ||
|
|
495a46e2d8 | ||
|
|
05bda1192e | ||
|
|
6058af0ca1 | ||
|
|
1eb8bf9719 | ||
|
|
afc02faeda | ||
|
|
66f22de90f | ||
|
|
2949a2e0ff | ||
|
|
ba12efea9d | ||
|
|
e1180a12fb | ||
|
|
1393706f13 | ||
|
|
6f994f31f7 | ||
|
|
38aa99a063 | ||
|
|
85c44b3529 | ||
|
|
e1a2768de5 | ||
|
|
e1c9b27203 | ||
|
|
969f6ef826 | ||
|
|
7abc4d4e76 | ||
|
|
ac97147c1f | ||
|
|
dbd20fe396 | ||
|
|
44e57c9c4b | ||
|
|
488e5e531f | ||
|
|
42a6a8d770 | ||
|
|
f8e877ea05 | ||
|
|
65d6fc7272 | ||
|
|
63ce8e461b | ||
|
|
fbf4c48461 | ||
|
|
81a55db644 | ||
|
|
4d4edfa181 | ||
|
|
6f9182f1f6 | ||
|
|
fa600c03e2 | ||
|
|
4a53301e9f | ||
|
|
676984b3d5 | ||
|
|
e6d7f7248b | ||
|
|
50903b5c4a | ||
|
|
01e399fb91 | ||
|
|
911aeb7af0 | ||
|
|
7e5cd9abbc | ||
|
|
115527a21a | ||
|
|
eff4f4f601 | ||
|
|
16e0099a0d | ||
|
|
2c8c678275 | ||
|
|
3b51e87fbf | ||
|
|
6c6eef5e2b | ||
|
|
6e5910f44c | ||
|
|
a967189bc6 | ||
|
|
7069176cf6 | ||
|
|
44dcbe773d | ||
|
|
ca76975461 | ||
|
|
83122ac99e | ||
|
|
c3e9458555 | ||
|
|
057ba38873 | ||
|
|
81d7d6236b | ||
|
|
191dd49653 | ||
|
|
21e9dd6f51 | ||
|
|
cc2d14acc6 | ||
|
|
87f37e9f1c | ||
|
|
d536a9f874 | ||
|
|
b45f353fa9 | ||
|
|
a3073ec14e | ||
|
|
f77eb33029 | ||
|
|
c1c919097a | ||
|
|
e05348463c | ||
|
|
fdcf74eaf2 | ||
|
|
6d57a3e3b9 | ||
|
|
1f449c866e | ||
|
|
e12deccd24 | ||
|
|
3184ebb5ee | ||
|
|
4a35ed2b35 | ||
|
|
5c9474d1c8 | ||
|
|
2321dc50c5 | ||
|
|
4efd2e8184 | ||
|
|
e30e153bfa | ||
|
|
2724211535 | ||
|
|
81068de0f1 | ||
|
|
7d842175f7 | ||
|
|
e0aee9f361 | ||
|
|
df576e2738 | ||
|
|
bb1356b25d | ||
|
|
1b67960da4 | ||
|
|
d76718e8b2 | ||
|
|
76c51922f1 | ||
|
|
f95e89a136 | ||
|
|
2dff60a23c | ||
|
|
95f83d1a29 | ||
|
|
b875ccecc1 | ||
|
|
e4c3802f16 | ||
|
|
081e485f4f | ||
|
|
4adf88da19 | ||
|
|
31e2b1b8d3 | ||
|
|
bd28abd343 | ||
|
|
955690b124 | ||
|
|
fa6f06ae15 | ||
|
|
263de140c5 | ||
|
|
ed85d06d69 | ||
|
|
4ff0870df8 | ||
|
|
410bac2040 | ||
|
|
38b1e367b1 | ||
|
|
3cddffa37f | ||
|
|
ea7a1a7175 | ||
|
|
36b5601588 | ||
|
|
7fc68f2969 | ||
|
|
c5ee07add4 | ||
|
|
32ff315b6b | ||
|
|
f919346f8f | ||
|
|
279df00404 | ||
|
|
bfd4b17fa0 | ||
|
|
5fe2817164 | ||
|
|
b337bb39bc | ||
|
|
65ae41c5f1 | ||
|
|
796c644c4a | ||
|
|
bfd9023a27 | ||
|
|
c9cdf5d03e | ||
|
|
f60bb41ad9 | ||
|
|
c333903b4a | ||
|
|
dd55e8a22c | ||
|
|
3ab9381d0a | ||
|
|
58f1fe0671 | ||
|
|
82b9c05d0f | ||
|
|
7c9397f7f6 | ||
|
|
6214b6a3ff | ||
|
|
883c8cc4c8 | ||
|
|
8d47c72913 | ||
|
|
89a6664e45 | ||
|
|
30d792d6e1 | ||
|
|
3745bf3157 | ||
|
|
a7fda3e50d | ||
|
|
7f07204fef | ||
|
|
8b51a44b7c | ||
|
|
c499c73dcc | ||
|
|
c01f3f5e8a | ||
|
|
2aef35655f | ||
|
|
7ddf1f5830 | ||
|
|
b2c513ea42 | ||
|
|
4c30f94355 | ||
|
|
e911e86c4c | ||
|
|
ca640b3f64 | ||
|
|
b4c4a05f3b | ||
|
|
fd3c36a259 | ||
|
|
d8274ac2d4 | ||
|
|
9c7479f953 | ||
|
|
b5dc3c4366 | ||
|
|
26b8082155 | ||
|
|
418df15f7b | ||
|
|
31ed0125b8 | ||
|
|
494318b879 | ||
|
|
f554ddc372 | ||
|
|
03de12c221 | ||
|
|
6c41f22b57 | ||
|
|
7ae96388e3 | ||
|
|
e8b4de00d2 | ||
|
|
cd7963b30d | ||
|
|
0dc44cffcf | ||
|
|
7a650132c5 | ||
|
|
c7fb390c38 | ||
|
|
572ff9df19 | ||
|
|
b715e0cef7 | ||
|
|
36ab2a889f | ||
|
|
a78d2f28d7 | ||
|
|
7d5a39ed89 | ||
|
|
772272ff36 | ||
|
|
2ab4eafee9 | ||
|
|
b15e0d4c45 | ||
|
|
b8180314d8 | ||
|
|
fcb8d03a0f | ||
|
|
09ec89bc2e | ||
|
|
863ad0f486 | ||
|
|
79a1bb3571 | ||
|
|
9f1d7323c7 | ||
|
|
64a82f4785 | ||
|
|
f37e4bd76e | ||
|
|
98ef2cc640 | ||
|
|
134222fd69 | ||
|
|
0cb2371517 | ||
|
|
b7de4359fd | ||
|
|
2607d6a107 | ||
|
|
db46b1ce13 | ||
|
|
d7b08d5207 | ||
|
|
29fbba832c | ||
|
|
fd621a442a | ||
|
|
a1a73568ae | ||
|
|
3daccbd6ec | ||
|
|
293deadb48 | ||
|
|
452b56c47b | ||
|
|
5cb6bfa633 | ||
|
|
0515cee6f3 | ||
|
|
4247112539 | ||
|
|
8d3374f574 | ||
|
|
26833e5f7c | ||
|
|
6752b46f67 | ||
|
|
b9429ffcaa | ||
|
|
10827c7e21 | ||
|
|
23cb4a34a4 | ||
|
|
adfd09565f | ||
|
|
78b9ff49d4 | ||
|
|
fca425d25e | ||
|
|
1a4238156c | ||
|
|
f6210cc014 | ||
|
|
6c8b466e59 | ||
|
|
2aebe97f9f | ||
|
|
157724bff8 | ||
|
|
6cbb1a0bee | ||
|
|
960a13dd38 | ||
|
|
9213f80435 | ||
|
|
bccae94c7a | ||
|
|
d71f77ce06 | ||
|
|
2787f3dc71 | ||
|
|
fb00baab5b | ||
|
|
9e22155d31 | ||
|
|
963373435d | ||
|
|
377987fa92 | ||
|
|
0b6980639e | ||
|
|
4f1cc9f94f | ||
|
|
6e5434a0ec | ||
|
|
3244f7c38f | ||
|
|
f27b676e89 | ||
|
|
4f2a80a4a3 | ||
|
|
a51bc27829 | ||
|
|
4fd321c93d | ||
|
|
bbd62bdef5 | ||
|
|
4bb1d78939 | ||
|
|
53c37ef413 | ||
|
|
a6511b6c5a | ||
|
|
829e96a2d0 | ||
|
|
2e25f37433 | ||
|
|
fbf6c73226 | ||
|
|
aab54e3f23 | ||
|
|
a6eff7fbfb | ||
|
|
d5667d2473 | ||
|
|
a42305dd59 | ||
|
|
c22a718d14 | ||
|
|
d0b23c79e2 | ||
|
|
76da04afd8 | ||
|
|
768f60709f | ||
|
|
8cd3acd318 | ||
|
|
ce7cfc0648 | ||
|
|
8b6cf55473 | ||
|
|
75d95d844c | ||
|
|
f54bfd3fb5 | ||
|
|
f8a8ee9b9d | ||
|
|
16faaae199 | ||
|
|
375417527b | ||
|
|
10b01ca6b3 | ||
|
|
f9006af04c | ||
|
|
57f947576e | ||
|
|
5a8f8c345b | ||
|
|
e96067e3c8 | ||
|
|
2242174515 | ||
|
|
73179c118b | ||
|
|
5b575134fc | ||
|
|
c11c06b896 | ||
|
|
ba8d2a251f | ||
|
|
c9589b73f4 | ||
|
|
32f4425100 | ||
|
|
05e81484f1 | ||
|
|
10cc79f737 | ||
|
|
957d9b180d | ||
|
|
883204fc43 | ||
|
|
6d3904fbbd | ||
|
|
56a51f18e7 | ||
|
|
307508b7a0 | ||
|
|
66fce79427 | ||
|
|
5e5708d8d4 | ||
|
|
944d92bbb4 | ||
|
|
0155d5aa39 | ||
|
|
fe4f45c2b0 | ||
|
|
1b63a58e63 | ||
|
|
46a141db9c | ||
|
|
66de06956c | ||
|
|
713dd62bd1 | ||
|
|
5ac65aafad | ||
|
|
4aef92e6fe | ||
|
|
a1b0e771e5 | ||
|
|
5baeac4706 | ||
|
|
87aa9bd673 | ||
|
|
2ec5ca56d5 | ||
|
|
b5c7f83ec8 | ||
|
|
eb3ebdbf52 | ||
|
|
c60698ff7e | ||
|
|
f8c2cda257 | ||
|
|
48f6c195e0 | ||
|
|
804fa60317 | ||
|
|
d77b99d3d4 | ||
|
|
006f1271d6 | ||
|
|
0d14514712 | ||
|
|
f25e5f9488 | ||
|
|
9e8bbfd175 | ||
|
|
3d11c96e23 | ||
|
|
a670737ca5 | ||
|
|
9fdd982e73 | ||
|
|
8024918e08 | ||
|
|
cda7607e1c | ||
|
|
816c83c80a | ||
|
|
0c3c490d58 | ||
|
|
99da6fb66f | ||
|
|
fa2601386c | ||
|
|
122833b0e3 | ||
|
|
8618dbf0d5 | ||
|
|
a0baf33459 | ||
|
|
0ee66ea928 | ||
|
|
f68d4aaf5b | ||
|
|
888abc9e2a | ||
|
|
c8115b1c10 | ||
|
|
137d4f591f | ||
|
|
337d49770d | ||
|
|
614c5578b0 | ||
|
|
d456e60800 | ||
|
|
064206fb9a | ||
|
|
a68fe3b39d | ||
|
|
1904c82941 | ||
|
|
6fc9dd4b30 | ||
|
|
158a31e924 | ||
|
|
b70b924db4 | ||
|
|
9018d72e97 | ||
|
|
5c395138ed | ||
|
|
af157adc1b | ||
|
|
1db4fca9db | ||
|
|
013f475859 | ||
|
|
b5bc38fa52 | ||
|
|
bd0e0cdfa4 | ||
|
|
dade4c4cc4 | ||
|
|
acc5a89dff | ||
|
|
d34881aa25 | ||
|
|
b8ad48997b | ||
|
|
77754b7246 | ||
|
|
6d5bf49a51 | ||
|
|
b7af635a9a | ||
|
|
f53b4e959c | ||
|
|
6716d156bb | ||
|
|
dc33e28452 | ||
|
|
9da4781759 | ||
|
|
0c6959cb4a | ||
|
|
ff3136df70 | ||
|
|
326c627221 | ||
|
|
075f382a8f | ||
|
|
dabb8fe49e | ||
|
|
90489e4392 | ||
|
|
ad45a74f87 | ||
|
|
60c045a713 | ||
|
|
f6c75e1f99 | ||
|
|
dd9245f6f2 | ||
|
|
7310a70743 | ||
|
|
82276837ac | ||
|
|
bd68252b44 | ||
|
|
6b1258e33a | ||
|
|
0400032923 | ||
|
|
d9563322f1 | ||
|
|
ab965969dd | ||
|
|
2f32e034d8 | ||
|
|
d7bb171c1e | ||
|
|
1cf7931f43 | ||
|
|
edc697dd73 | ||
|
|
54a059ff68 | ||
|
|
289282e235 | ||
|
|
825c36c15e | ||
|
|
1234c2e99e | ||
|
|
b8fae1308d | ||
|
|
dddcf624e6 | ||
|
|
b33fe9f7fe | ||
|
|
5a799400a9 | ||
|
|
76919a819f | ||
|
|
9c30f846b2 | ||
|
|
9230f51988 | ||
|
|
712035dc9a | ||
|
|
32e5c5b4ad | ||
|
|
134a6fab7e | ||
|
|
82e27cb962 | ||
|
|
8bcad7b3f9 | ||
|
|
d767575f76 | ||
|
|
7214c7d393 | ||
|
|
205e5ab03d | ||
|
|
6576beae76 | ||
|
|
001f8f1f50 | ||
|
|
3b694a87ef | ||
|
|
84dd06d769 | ||
|
|
c5cb16abfb | ||
|
|
79fb34324d | ||
|
|
303aef3548 | ||
|
|
fd278f8c32 | ||
|
|
53041a4117 | ||
|
|
9b3fe3b13a | ||
|
|
5c6c5081e9 | ||
|
|
e087ea0ac7 | ||
|
|
71c44dc805 | ||
|
|
c5c8596664 | ||
|
|
92a86f4d1c | ||
|
|
8098b68b8e | ||
|
|
7356001723 | ||
|
|
aba60587ab | ||
|
|
936a6a04fb | ||
|
|
9675126298 | ||
|
|
6a5886ea1c | ||
|
|
648c6a5a8f | ||
|
|
14b7bf4753 | ||
|
|
0e310fa96a | ||
|
|
0f6c282c80 | ||
|
|
ed3cd0c9c8 | ||
|
|
398f029f6d | ||
|
|
ad9c2b917b | ||
|
|
d0d65182c0 | ||
|
|
4c3a0d329b | ||
|
|
7c495c2177 | ||
|
|
2f86a9e534 | ||
|
|
12c3a0b1fa | ||
|
|
14f3660f55 | ||
|
|
5a8b032d74 | ||
|
|
57c4613b1f | ||
|
|
e008021a42 | ||
|
|
7e600c43ed | ||
|
|
963478e206 | ||
|
|
0f32783488 | ||
|
|
756d470715 | ||
|
|
2c47b7535b | ||
|
|
4cc90b4929 | ||
|
|
32754ffcf5 | ||
|
|
64aae75680 | ||
|
|
69d2160a0d | ||
|
|
99e326539e | ||
|
|
1dde975cfe | ||
|
|
58c069ec5c | ||
|
|
7916600a7b | ||
|
|
3e4f160c5d | ||
|
|
aeb5e5f681 | ||
|
|
1c2e491845 | ||
|
|
eb4000f26b | ||
|
|
74dd887c79 | ||
|
|
764599a7d9 | ||
|
|
ad683fee89 | ||
|
|
85a53fc68f | ||
|
|
3bf8baee85 | ||
|
|
8792213594 | ||
|
|
d9ebc9455c | ||
|
|
9ab8bdfe4a | ||
|
|
418ea9a19e | ||
|
|
20f04febf2 | ||
|
|
a65783201e | ||
|
|
a5f04d44a4 | ||
|
|
cbe1022f20 | ||
|
|
90301ae9ee | ||
|
|
4f38ab3640 | ||
|
|
fca179abab | ||
|
|
e426237c35 | ||
|
|
3dae361d7b | ||
|
|
967831388e | ||
|
|
f9794f20d4 | ||
|
|
f98efd6af0 | ||
|
|
69bf0641f8 | ||
|
|
5791843d16 | ||
|
|
58d0a20074 | ||
|
|
5884c7b3ba | ||
|
|
dd1da268a2 | ||
|
|
473f3954c7 | ||
|
|
5aad5406a2 | ||
|
|
98b606287d | ||
|
|
9792fc0daa | ||
|
|
a9bb9302bc | ||
|
|
30c70bc8d4 | ||
|
|
0df48c37ac | ||
|
|
ec31e94e7a | ||
|
|
ea631d0e88 | ||
|
|
66a180346e | ||
|
|
63ee878789 | ||
|
|
3479e4f2fd | ||
|
|
54f4152f89 | ||
|
|
06334bf272 | ||
|
|
839f096f39 | ||
|
|
f3b2fdc4fc | ||
|
|
16d34f3268 | ||
|
|
61e8dd09d6 | ||
|
|
90d7fea7aa | ||
|
|
b9c8bf07ea | ||
|
|
a3ba07d45f | ||
|
|
5a6a29cbb5 | ||
|
|
72aedbb76c | ||
|
|
e7e3be6ea7 | ||
|
|
62e1b9eb01 | ||
|
|
3fff92dc35 | ||
|
|
352d77719e | ||
|
|
ff397dfa4d | ||
|
|
34d64c0dff | ||
|
|
b5fdc2f956 | ||
|
|
38602965db | ||
|
|
df1ea62883 | ||
|
|
afaff52888 | ||
|
|
5b7829c288 | ||
|
|
2462eb2c79 | ||
|
|
edc26b0a55 | ||
|
|
cc94e8b0ca | ||
|
|
80f3a6e507 | ||
|
|
5709be7ff7 | ||
|
|
46fce8cf4b | ||
|
|
e84049367e | ||
|
|
f213ead595 | ||
|
|
ba540b0725 | ||
|
|
eb55691c89 | ||
|
|
dd508e7dea | ||
|
|
66357866c5 | ||
|
|
6e3728b458 | ||
|
|
31d4eef4b1 | ||
|
|
f58f32a7a8 | ||
|
|
28d8fb686a | ||
|
|
4c7fc2ef47 | ||
|
|
a3f99978c2 | ||
|
|
136b55d310 | ||
|
|
617e90259b | ||
|
|
959eb46162 | ||
|
|
998bda9de7 | ||
|
|
37a2018fe3 | ||
|
|
2c80e07c9d | ||
|
|
a115f34766 | ||
|
|
cd66c1e7c3 | ||
|
|
4f9975dc6d | ||
|
|
9da487d962 | ||
|
|
c7123b016b | ||
|
|
efb13ddaf0 | ||
|
|
3539b73c08 | ||
|
|
2c084ef4d5 | ||
|
|
754e66f4dd | ||
|
|
41b698f0a8 | ||
|
|
de78da4fa6 | ||
|
|
3d241d6fa1 | ||
|
|
1d983a0090 | ||
|
|
78fb860305 | ||
|
|
c699a84f42 | ||
|
|
d8a178d93d | ||
|
|
ada4243548 | ||
|
|
fa2e3aad6c | ||
|
|
0cf457a46f | ||
|
|
bb7b98d448 | ||
|
|
e8d90848f2 | ||
|
|
7c791451ba | ||
|
|
16d8c2b221 | ||
|
|
dceecbef0a | ||
|
|
3cbddf1de9 | ||
|
|
650340fcb3 | ||
|
|
ce5b893224 | ||
|
|
7869afa4ff | ||
|
|
9085606082 | ||
|
|
1e3f646814 | ||
|
|
933f0cb4b8 | ||
|
|
7497761fcc | ||
|
|
12b3d4ec7a | ||
|
|
8fd5ed57c4 | ||
|
|
7bc301bc70 | ||
|
|
30321d3a0e | ||
|
|
511a0ae503 | ||
|
|
1057636666 | ||
|
|
564b1d2a98 | ||
|
|
20cd0e2de2 | ||
|
|
6bc617c488 | ||
|
|
049db83423 | ||
|
|
52dd90e85d | ||
|
|
305267d07f | ||
|
|
20369aa1b5 | ||
|
|
40f05e4dbb | ||
|
|
a23d19f208 | ||
|
|
cb1d1e8ed7 | ||
|
|
4f67f32719 | ||
|
|
a80b5b6abc | ||
|
|
0be3d88872 | ||
|
|
48bb996350 | ||
|
|
ee2dde4cd1 | ||
|
|
c10a31c933 | ||
|
|
d6a846f58d | ||
|
|
945873231d | ||
|
|
5dc494978e | ||
|
|
c870ec10c0 | ||
|
|
2085b8fd14 | ||
|
|
e065b6435c | ||
|
|
da5331ceb0 | ||
|
|
8f81982de4 | ||
|
|
499b46ecf3 | ||
|
|
a7d232e15f | ||
|
|
8fdb394ec5 | ||
|
|
7a1da64bf2 | ||
|
|
95ae155fc0 | ||
|
|
d1507f2666 | ||
|
|
7e4f98d328 | ||
|
|
f9a956905e | ||
|
|
e7d95f9da6 | ||
|
|
bc8f0aa223 | ||
|
|
6f2ae94e12 | ||
|
|
8f787e9976 | ||
|
|
321d8240a2 | ||
|
|
d667b2f822 | ||
|
|
d7f511363d | ||
|
|
39e7c5c3de | ||
|
|
60acd5c864 | ||
|
|
b92cf6fd35 | ||
|
|
f7d048e0b9 | ||
|
|
b3d79622e6 | ||
|
|
7e7ae79477 | ||
|
|
0f9482864c | ||
|
|
60700d59fe | ||
|
|
3296cef02d | ||
|
|
1b55b5fa3c | ||
|
|
5910988314 | ||
|
|
8c4b1ef74a | ||
|
|
b2701f5ba4 | ||
|
|
7d4f1941e7 | ||
|
|
eedefcdbbb | ||
|
|
bdb5e82abc | ||
|
|
ff766a46c8 | ||
|
|
0a40dc5939 | ||
|
|
71862d76d3 | ||
|
|
7a35cc3d17 | ||
|
|
7a4870c977 | ||
|
|
d4d2792498 | ||
|
|
a969509283 | ||
|
|
82fa340c07 | ||
|
|
d44cd4a827 | ||
|
|
a8dbe65e30 | ||
|
|
d2ce7c11ac | ||
|
|
d02af5ccb0 | ||
|
|
9a5467dcac | ||
|
|
2af4f61882 | ||
|
|
cbd06eef96 | ||
|
|
392dc2a040 | ||
|
|
da11702f68 | ||
|
|
f262bf7cdb | ||
|
|
78ab5ad156 | ||
|
|
6af796fc3b | ||
|
|
c174be37b3 | ||
|
|
18aa067c44 | ||
|
|
8d50b338f4 | ||
|
|
37d7cfaaf2 | ||
|
|
d3564a9a4f | ||
|
|
39d6dd9916 | ||
|
|
0152ebf062 | ||
|
|
757b9b2118 | ||
|
|
f6a01551fd | ||
|
|
1f619f3801 | ||
|
|
fd436cf5b2 | ||
|
|
7e05ce38cf | ||
|
|
7d1e977ffe | ||
|
|
6c2ce83b45 | ||
|
|
d5ba0eebcb | ||
|
|
432585cb75 | ||
|
|
e41a341ce6 | ||
|
|
5d9a4b42a6 | ||
|
|
6aad80904a | ||
|
|
20e796cef4 | ||
|
|
a3b126282d | ||
|
|
5f597379b5 | ||
|
|
9d8460bb81 | ||
|
|
8943af9840 | ||
|
|
d23c718036 | ||
|
|
834c84c9ea | ||
|
|
adc436a3f5 | ||
|
|
e325bf7771 | ||
|
|
feabd07a21 | ||
|
|
e138c6fd61 | ||
|
|
d32299fde5 | ||
|
|
3d7d780e8f | ||
|
|
9f49854033 | ||
|
|
1fe820d463 | ||
|
|
4a78690fde | ||
|
|
3dcaf5a9de | ||
|
|
ff788852d6 | ||
|
|
5ae062719e | ||
|
|
421c0a11fb | ||
|
|
6ae586aeb7 | ||
|
|
7036423084 | ||
|
|
2f118a9cbe | ||
|
|
2c50255b21 | ||
|
|
8cb7210c46 | ||
|
|
ad0a24ad2f | ||
|
|
df6c951830 | ||
|
|
5da2caa616 | ||
|
|
a3fe95d1e4 | ||
|
|
38e61c121b | ||
|
|
03e9623073 | ||
|
|
93a1657e1e | ||
|
|
91d67fb72f | ||
|
|
d8cc1f885c | ||
|
|
c1f999d896 | ||
|
|
efc4d0f59b | ||
|
|
cf55d670b9 | ||
|
|
8567c5e6a1 | ||
|
|
331084fefd | ||
|
|
62bf691ac1 | ||
|
|
09b41d4665 | ||
|
|
71645240e9 | ||
|
|
603468823d | ||
|
|
01f464cc69 | ||
|
|
57ac6e982f | ||
|
|
319d2d1efe | ||
|
|
37de3a4122 | ||
|
|
bb3a49264d | ||
|
|
9cecce74fa | ||
|
|
f9cf2878ef | ||
|
|
9c80b7cf54 | ||
|
|
1ecad7031f | ||
|
|
c85d6107ec | ||
|
|
7b7445b601 | ||
|
|
1ab474673d | ||
|
|
dbf92e7f20 | ||
|
|
6c42db2508 | ||
|
|
c9a42178e8 | ||
|
|
eff48dfe67 | ||
|
|
0c38bdc068 | ||
|
|
b8e1736696 | ||
|
|
c2f36444d0 | ||
|
|
5dc74f5b4d | ||
|
|
9694dfe4cc | ||
|
|
734125ea14 | ||
|
|
438f5d1b87 | ||
|
|
fadd6d7978 | ||
|
|
5026262273 | ||
|
|
5b53fba020 | ||
|
|
3892e6e16f | ||
|
|
33467de763 | ||
|
|
f3528d97c2 | ||
|
|
6fb3b01bf0 | ||
|
|
e3c9cec440 | ||
|
|
0e011425fb | ||
|
|
ba658f7fea | ||
|
|
0e6087143b | ||
|
|
5f967e6307 | ||
|
|
2eb8ce632c | ||
|
|
f25dbd15d9 | ||
|
|
cc5ea77170 | ||
|
|
e323644af2 | ||
|
|
61f3a3219f | ||
|
|
4dcf5dbc13 | ||
|
|
8faecba0a2 | ||
|
|
739551cbe3 | ||
|
|
24a2e42881 | ||
|
|
6921754c99 | ||
|
|
d8827a0b44 | ||
|
|
a48091988f | ||
|
|
9bd9c9cf1f | ||
|
|
695692285b | ||
|
|
03edacf7b6 | ||
|
|
4802c97e89 | ||
|
|
9fc24d1981 | ||
|
|
d4ddf453b0 | ||
|
|
c0117f07cf | ||
|
|
8a88c14b13 | ||
|
|
a5b6302a69 | ||
|
|
9f29d4619d | ||
|
|
f4b9dd7d7b | ||
|
|
c0a4152b00 | ||
|
|
efb87c5a9e | ||
|
|
061e8bb662 | ||
|
|
a4f42b2948 | ||
|
|
cb2fcd3a9e | ||
|
|
1d004a35a0 | ||
|
|
c763c02018 | ||
|
|
eb36cb4436 | ||
|
|
72d4b9bf62 | ||
|
|
81ea138f41 | ||
|
|
1bbc66ad62 | ||
|
|
e7348df372 | ||
|
|
550e060647 | ||
|
|
2970a58e95 | ||
|
|
e0efa04fd4 | ||
|
|
4d24088982 | ||
|
|
baba9f5de6 | ||
|
|
c35cd63d0e | ||
|
|
80fa389ce3 | ||
|
|
8ec861c9fe | ||
|
|
837400fb5e | ||
|
|
ec4525b8ff | ||
|
|
281c927971 | ||
|
|
9dd44c13e4 | ||
|
|
f28edbcf8f | ||
|
|
29e147f992 | ||
|
|
830f4231e1 | ||
|
|
7d65e31055 | ||
|
|
dec7a91b5b | ||
|
|
1ba630c221 | ||
|
|
7d3387fb96 | ||
|
|
a0c0de28d7 | ||
|
|
dc31d52f83 | ||
|
|
620c822dac | ||
|
|
5990f5ae22 | ||
|
|
37329a50d4 | ||
|
|
550597f72e | ||
|
|
2aa4022e2c | ||
|
|
b40741b14d | ||
|
|
3c739d889e | ||
|
|
24a92a133e | ||
|
|
ce97eb5b40 | ||
|
|
7a4e3c480e | ||
|
|
eefa710839 | ||
|
|
4c3e1afcca | ||
|
|
c1a77ada5d | ||
|
|
5671e5ed67 | ||
|
|
2fdc5a8541 | ||
|
|
297dbae247 | ||
|
|
0910cdf3a4 | ||
|
|
6877fb5c74 | ||
|
|
2d65daa8c9 | ||
|
|
dab4cb6186 | ||
|
|
40773a2b49 | ||
|
|
7e0d61a6fc | ||
|
|
7f9620d75f | ||
|
|
3559aef1a1 | ||
|
|
94ceb5eaaf | ||
|
|
778ca76d22 | ||
|
|
b1c0e41c5c | ||
|
|
f826edd097 | ||
|
|
edc7c4a4b8 | ||
|
|
dafdc66d25 | ||
|
|
0d135f14bb | ||
|
|
568c08d0e9 | ||
|
|
87410e295e | ||
|
|
b163e68950 | ||
|
|
88b006e957 | ||
|
|
477f2f2814 | ||
|
|
933d99c23b | ||
|
|
d3a0c5ded1 | ||
|
|
1e173ddc24 | ||
|
|
ca404cb33b | ||
|
|
f0dc7d5b02 | ||
|
|
933702376f | ||
|
|
e08896775b | ||
|
|
d610e46f8e | ||
|
|
7d1989f5a2 | ||
|
|
5c1e371427 | ||
|
|
dbd9d51747 | ||
|
|
fdf5d3f72d | ||
|
|
2719867a86 | ||
|
|
0240412ad2 | ||
|
|
7c065c1205 | ||
|
|
f9aa1ad1f2 | ||
|
|
5feffdf544 | ||
|
|
4e56b8bb78 | ||
|
|
845017313c | ||
|
|
dc2830d94f | ||
|
|
552edf8698 | ||
|
|
41c51646fe | ||
|
|
a42024bdbc | ||
|
|
20cfb26a7f | ||
|
|
3972d11827 | ||
|
|
5cc88a0075 | ||
|
|
fc08711111 | ||
|
|
b20c2babec | ||
|
|
cb0facc6ef | ||
|
|
78abb2edcb | ||
|
|
7d350d9def | ||
|
|
48d7daf2c4 | ||
|
|
2782059d88 | ||
|
|
0ca10bc2ac | ||
|
|
880abe2305 | ||
|
|
22f61d6225 | ||
|
|
4fbaa425fb | ||
|
|
e81e228f03 | ||
|
|
1076f89954 | ||
|
|
9c6f977202 | ||
|
|
bd23ba6077 | ||
|
|
c7af56d0ed | ||
|
|
8da6db9fcc | ||
|
|
2fe7342fd7 | ||
|
|
f6221144a8 | ||
|
|
872d713e50 | ||
|
|
d5b04f572b | ||
|
|
0f7a5f1c08 | ||
|
|
a163c565a8 | ||
|
|
413a316b15 | ||
|
|
65a92a49b5 | ||
|
|
563507ca21 | ||
|
|
21b2d02f0a | ||
|
|
19e1a00fd7 | ||
|
|
a02a6a22d0 | ||
|
|
3488421f67 | ||
|
|
34a961088c | ||
|
|
b35509150a | ||
|
|
d096aa2065 | ||
|
|
efd5bef102 | ||
|
|
b8c6e44ab6 | ||
|
|
9a91cc43e2 | ||
|
|
f4cbab52a7 | ||
|
|
57b58cf203 | ||
|
|
9ba8ae08a1 | ||
|
|
dfe81f510e | ||
|
|
f3a0b35442 | ||
|
|
64e3be3bc7 | ||
|
|
4c82d1c56e | ||
|
|
d8451fc2f5 | ||
|
|
8078423252 | ||
|
|
68176b5695 | ||
|
|
1bf7833959 | ||
|
|
89770b922d | ||
|
|
716947bbb1 | ||
|
|
47e0d7786b | ||
|
|
55f9c40bba | ||
|
|
51afa30732 | ||
|
|
23c07316ee | ||
|
|
e740f52e5e | ||
|
|
a731109747 | ||
|
|
a50a011eb3 | ||
|
|
e22c6d3a94 | ||
|
|
50fb9c1795 | ||
|
|
22575c9a01 | ||
|
|
2934922cb5 | ||
|
|
9042ff46c7 | ||
|
|
a1a91539c2 | ||
|
|
468f4f94a3 | ||
|
|
3ebd35437e | ||
|
|
a166bbadad | ||
|
|
7ff07a132a | ||
|
|
6f297bcbb8 | ||
|
|
1c023e15af | ||
|
|
37f96848a7 | ||
|
|
3d04765f51 | ||
|
|
e1152fa549 | ||
|
|
ab47896f17 | ||
|
|
4f13565e51 | ||
|
|
7ab93a59e2 | ||
|
|
943c0d022b | ||
|
|
bea8922c39 | ||
|
|
97c96a7ee1 | ||
|
|
3d831ba7e8 | ||
|
|
df749a98cb | ||
|
|
22bbc9c621 | ||
|
|
30def4e515 | ||
|
|
cf8be37310 | ||
|
|
12409df446 | ||
|
|
3452a08de3 | ||
|
|
425ea0579e | ||
|
|
22afb769af | ||
|
|
884eae269e | ||
|
|
59a973970e | ||
|
|
225383464a | ||
|
|
3d82731325 | ||
|
|
dacdf08309 | ||
|
|
ad281adc97 | ||
|
|
80741c7773 | ||
|
|
532f7a4b17 | ||
|
|
5e87d582e4 | ||
|
|
b9bf47aaca | ||
|
|
0dba882817 | ||
|
|
c419883814 | ||
|
|
6f0ccbf2b5 | ||
|
|
54332c0bd1 | ||
|
|
5f80674e89 | ||
|
|
c4d0d8ff06 | ||
|
|
8ac1b7082a | ||
|
|
f146ae8be4 | ||
|
|
e7728fdc94 | ||
|
|
052122e4d0 | ||
|
|
38827d2b3d | ||
|
|
9e1f16be27 | ||
|
|
c845846317 | ||
|
|
9276556f19 | ||
|
|
c796d18948 | ||
|
|
8dee5520cf | ||
|
|
440e13714e | ||
|
|
44a70b372d | ||
|
|
504286e96e | ||
|
|
ffdd54d2fa | ||
|
|
32804b81c0 | ||
|
|
403b22ade0 | ||
|
|
a4e74abcca | ||
|
|
8dcef5bac0 | ||
|
|
49878bc4e3 | ||
|
|
3f1a71c8a4 | ||
|
|
bf9b2c0da3 | ||
|
|
909a274709 | ||
|
|
fc529b8083 | ||
|
|
f1386f26fb | ||
|
|
cccd09d329 | ||
|
|
0fccf7effe | ||
|
|
4b91a47c8b | ||
|
|
bd40499bbe | ||
|
|
c7c8cd76c6 | ||
|
|
0bb9f0ce41 | ||
|
|
7136afce8e | ||
|
|
ec17c1de6a | ||
|
|
8d6daef354 | ||
|
|
3a09d2de4a | ||
|
|
c78e10f92e | ||
|
|
b113ff35ac | ||
|
|
6360024d20 | ||
|
|
a7683f6bd7 | ||
|
|
e46a9f3f2a | ||
|
|
a8d711d4c8 | ||
|
|
df74fc67bd | ||
|
|
450261abbf | ||
|
|
12230edc54 | ||
|
|
d1cfcf561b | ||
|
|
d143f5af8b | ||
|
|
0f7ae3cda7 | ||
|
|
baf94e56c8 | ||
|
|
905bd1a4c9 | ||
|
|
96bcf24047 | ||
|
|
dfe47235cf | ||
|
|
b82ea8eaa8 | ||
|
|
b1b830c268 | ||
|
|
e654d4a6df | ||
|
|
ac30b17ecb | ||
|
|
95efdb3a51 | ||
|
|
49c165e203 | ||
|
|
a4be351d9f | ||
|
|
3d0401aecd | ||
|
|
7c27572a53 | ||
|
|
1e7760012e | ||
|
|
24d464b6e5 | ||
|
|
499d91f9f8 | ||
|
|
8e0ceaa06b | ||
|
|
4e62641f7e | ||
|
|
688644f5a4 | ||
|
|
4703f2d1f5 | ||
|
|
14149ae949 | ||
|
|
a0fb0d170c | ||
|
|
e133afec86 | ||
|
|
3ae8ee8ddb | ||
|
|
012643a231 | ||
|
|
dccb43f4dc | ||
|
|
15b3bc6a63 | ||
|
|
2d15bef76d | ||
|
|
756d298f04 | ||
|
|
9f35eb1a85 | ||
|
|
c905bb4b6c | ||
|
|
c78af01c8f | ||
|
|
084855645a | ||
|
|
afce9ece89 | ||
|
|
154e50e36d | ||
|
|
80a129102b | ||
|
|
93672a074e | ||
|
|
c7f6f6233c | ||
|
|
68915a9daf | ||
|
|
13eb91f8dd | ||
|
|
1a8355e6fb | ||
|
|
aa2b7ae60a | ||
|
|
acd36b7ea5 | ||
|
|
87245ab79f | ||
|
|
13b6a17827 | ||
|
|
615e4cf24e | ||
|
|
0e6d08f027 | ||
|
|
d593e584dd | ||
|
|
e046b97160 | ||
|
|
567d3dac55 | ||
|
|
a67a0aa924 | ||
|
|
1b1e3e88fe | ||
|
|
ec99636ef0 | ||
|
|
9d955d252a | ||
|
|
f136f6837a | ||
|
|
6fc1fb0966 | ||
|
|
fad203a66d | ||
|
|
c1bab63ebd | ||
|
|
40f012b03c | ||
|
|
a380059389 | ||
|
|
24b998ba2d | ||
|
|
9a1bb09c9f | ||
|
|
3ad66f8937 | ||
|
|
a6f3e7df55 | ||
|
|
9345d3be31 | ||
|
|
8e85bf8839 | ||
|
|
1012dcd194 | ||
|
|
70251ea11e | ||
|
|
9381471fbd | ||
|
|
1c4b716f1a | ||
|
|
c8b0584127 | ||
|
|
5194a361f4 | ||
|
|
c44e5d2a87 | ||
|
|
ee4d514b66 | ||
|
|
863995cb50 | ||
|
|
cbfe72a76e | ||
|
|
4f17d3519c | ||
|
|
3cfcad76ac | ||
|
|
1ca6535811 | ||
|
|
53612ad2e4 | ||
|
|
4b799d264c | ||
|
|
ca5594703a | ||
|
|
7fc2d9dcca | ||
|
|
c413fc1e30 | ||
|
|
b5086c7759 | ||
|
|
92a015ca4d | ||
|
|
3b2802e36d | ||
|
|
7bf23eaa15 | ||
|
|
9afd1c5ee8 | ||
|
|
5e36377b36 | ||
|
|
c988df13a8 | ||
|
|
29a40d31b7 | ||
|
|
ddc27e818b | ||
|
|
3fa70ac841 | ||
|
|
b2b7dfaf37 | ||
|
|
c309c2cf13 | ||
|
|
71304b114a | ||
|
|
0ffcbdbd38 | ||
|
|
e368a17420 | ||
|
|
2fcfb2f67d | ||
|
|
f68a85056e | ||
|
|
943f47d29d | ||
|
|
fd37a2c466 | ||
|
|
eacdd7afe8 | ||
|
|
fe5ea52cdf | ||
|
|
ca6d77cbb3 | ||
|
|
1145941d11 | ||
|
|
d61697a152 | ||
|
|
38b77a9c79 | ||
|
|
7d294ee8c2 | ||
|
|
33d9422d03 | ||
|
|
bb7302c23a | ||
|
|
d50ae63a5a | ||
|
|
1961836e19 | ||
|
|
f2ed7c15ce | ||
|
|
4dce173630 | ||
|
|
86f868b2d4 | ||
|
|
363064f5c0 | ||
|
|
9d99ee9cfc | ||
|
|
db8969707d | ||
|
|
a24ac37dfd | ||
|
|
1b04d471b3 | ||
|
|
9cc400a081 | ||
|
|
e233aeec0c | ||
|
|
5dfd621900 | ||
|
|
f0f6a9988f | ||
|
|
587438938c | ||
|
|
2497ac68d1 | ||
|
|
75918c59cc | ||
|
|
8b38a20c18 | ||
|
|
e7b76bfdc5 | ||
|
|
3503ff6d36 | ||
|
|
192e21a9fc | ||
|
|
24e288d584 | ||
|
|
0e5ffda5e5 | ||
|
|
cdf6f18ec0 | ||
|
|
188245fa7f | ||
|
|
e10b747d6a | ||
|
|
f2bb6a05a5 | ||
|
|
f41da19db5 | ||
|
|
d0a56dbb21 | ||
|
|
acbf286e59 | ||
|
|
0f7c160409 | ||
|
|
5113aacb89 | ||
|
|
4e31636181 | ||
|
|
1e497d2c44 | ||
|
|
70bd4fa161 | ||
|
|
65996050d5 | ||
|
|
7f52031199 | ||
|
|
5430f3d33c | ||
|
|
43075faaf8 | ||
|
|
f3a1272e31 | ||
|
|
41c028d4d9 | ||
|
|
a17ce04552 | ||
|
|
d0b4652dcd | ||
|
|
e66f71c76e | ||
|
|
6effd4b846 | ||
|
|
df861f5403 | ||
|
|
e74346fed6 | ||
|
|
6961c467a6 | ||
|
|
892d305165 | ||
|
|
fa16261d7a | ||
|
|
15991fd2f7 | ||
|
|
c80b8f60f8 | ||
|
|
ab6253cbd0 | ||
|
|
35ba267115 | ||
|
|
ab24e6e1c1 | ||
|
|
e25ae27a15 | ||
|
|
2b7c524908 | ||
|
|
0b069df9ce | ||
|
|
60c9ba88ae | ||
|
|
cc2e60c84a | ||
|
|
83c2c4e92e | ||
|
|
ab3d9e82ef | ||
|
|
b6063dd534 | ||
|
|
e6754354e4 | ||
|
|
4849619d67 | ||
|
|
9b0ace242a | ||
|
|
e94ba74058 | ||
|
|
569fa06d2d | ||
|
|
46dce17abc | ||
|
|
40d8f4a352 | ||
|
|
6415785220 | ||
|
|
7735edeae8 | ||
|
|
0f81d1dbb3 | ||
|
|
ae1ec8b558 | ||
|
|
09c2b39530 | ||
|
|
b443e866f9 | ||
|
|
d4404713a8 | ||
|
|
47409a9a99 | ||
|
|
60bfea2d3b | ||
|
|
d3ed8eaed5 | ||
|
|
692dccf110 | ||
|
|
92caf98683 | ||
|
|
6178d38895 | ||
|
|
40fb38a9ba | ||
|
|
20e68d53fd | ||
|
|
2d3557e049 | ||
|
|
d8f4bc7395 | ||
|
|
353f9bb809 | ||
|
|
ccfe3ad4f7 | ||
|
|
9012820c03 | ||
|
|
fe2af19e42 | ||
|
|
f721e053f1 | ||
|
|
e6ad9feb84 | ||
|
|
635350c40e | ||
|
|
17edd33703 | ||
|
|
b0f2a871c6 | ||
|
|
8928a8a1dc | ||
|
|
2b6f37a6cc | ||
|
|
f3a3b87861 | ||
|
|
9cf6ee78d4 | ||
|
|
bbc2f3962f | ||
|
|
be49eb22d2 | ||
|
|
fb47067215 | ||
|
|
2c80ef178d | ||
|
|
9af8112148 | ||
|
|
57c36f437a | ||
|
|
5ed8a34566 | ||
|
|
ea8df9bd61 | ||
|
|
b0c51e03b7 | ||
|
|
336924ef23 | ||
|
|
ad28ca4a90 | ||
|
|
aebbe86cfc | ||
|
|
df9faf4943 | ||
|
|
3e295b6be4 | ||
|
|
8dd6dbf995 | ||
|
|
612139f2ff | ||
|
|
240bcabb76 | ||
|
|
cda27d5963 | ||
|
|
2f8c3997f7 | ||
|
|
46b89a48db | ||
|
|
5c9cbee2f9 | ||
|
|
ee8973c239 | ||
|
|
2e2813f363 | ||
|
|
7ceca0769f | ||
|
|
4d277cc61f | ||
|
|
e67fbb4621 | ||
|
|
29b5357ceb | ||
|
|
9dabec107b | ||
|
|
f2a2ad90b7 | ||
|
|
cfe4c0c510 | ||
|
|
23cd51a6da | ||
|
|
7396395f90 | ||
|
|
a1819bf232 | ||
|
|
8accf07d46 | ||
|
|
6dcbace572 | ||
|
|
e90c86ec2f | ||
|
|
971ae1fa4d | ||
|
|
4abe87036c | ||
|
|
8d1b44db97 | ||
|
|
b537f9925b | ||
|
|
f2fe8eaf86 | ||
|
|
46715cac08 | ||
|
|
0f21eba57f | ||
|
|
cb7620395a | ||
|
|
3a40af8871 | ||
|
|
c9b5074bc4 | ||
|
|
44d4d0d767 | ||
|
|
64af13f40d | ||
|
|
e9b59c6bef | ||
|
|
3d03659508 | ||
|
|
0374d2de48 | ||
|
|
2627dc5ee4 | ||
|
|
5554332b5b | ||
|
|
1cffea892b | ||
|
|
fd859815b0 | ||
|
|
166e26d101 | ||
|
|
be081eec3f | ||
|
|
55b00a87f6 | ||
|
|
429b26cee8 | ||
|
|
fafe6b0ff7 | ||
|
|
5b156006fb | ||
|
|
75f0c08ca4 | ||
|
|
1f4325e7db | ||
|
|
f2e7b40425 | ||
|
|
4ee3086b6d | ||
|
|
a3a715c3ba | ||
|
|
6cad4a3c33 | ||
|
|
b9b6f4fd44 | ||
|
|
17d1994a53 | ||
|
|
13184e72e1 | ||
|
|
911e8d21a7 | ||
|
|
5b69a2925f | ||
|
|
d1c900a620 | ||
|
|
6bfeb54f3c | ||
|
|
198fede915 | ||
|
|
1212ae3eb3 | ||
|
|
1266dcc0c7 | ||
|
|
6fcddf4a47 | ||
|
|
dfea424b94 | ||
|
|
9d03435aa1 | ||
|
|
26c20a7a22 | ||
|
|
470da06ecf | ||
|
|
a746a310bc | ||
|
|
3dbb516084 | ||
|
|
32177283b3 | ||
|
|
3a66e90b7a | ||
|
|
a454fb10ec | ||
|
|
b5386a35ee | ||
|
|
11651da411 | ||
|
|
88d52c44ad | ||
|
|
2d7d4bbd4e | ||
|
|
e6ee278fde | ||
|
|
6380cf9ed0 | ||
|
|
2e78dc52c7 | ||
|
|
ccb42d3249 | ||
|
|
c5009ab44b | ||
|
|
9d15cd43a3 | ||
|
|
0780e10fa2 | ||
|
|
0731f63237 | ||
|
|
a29896042b | ||
|
|
68ebc08c9d | ||
|
|
a1df526f93 | ||
|
|
0023ecefa4 | ||
|
|
511f156603 | ||
|
|
3f223b1ba0 | ||
|
|
a1528a1a63 | ||
|
|
b8bfddbf3a | ||
|
|
47fc813027 | ||
|
|
c7f2228a44 | ||
|
|
b0e0f045f8 | ||
|
|
1296514794 | ||
|
|
18e797095f | ||
|
|
85aa2ad4e6 | ||
|
|
818f6dc045 | ||
|
|
1c162c6390 | ||
|
|
def3a28fb5 | ||
|
|
d1378a0236 | ||
|
|
e544c7a65a | ||
|
|
24f48f668c | ||
|
|
9988a090ac | ||
|
|
d36e145d06 | ||
|
|
498d63ea00 | ||
|
|
7dc620a3ba | ||
|
|
66145e1d23 | ||
|
|
7bf8621afe | ||
|
|
ce3f74232e | ||
|
|
5b92d4b88c | ||
|
|
4daf6ba057 | ||
|
|
955e9899af | ||
|
|
fa3d0887ef | ||
|
|
5d5c6cf71c | ||
|
|
89aac45f41 | ||
|
|
4965fd5f4c | ||
|
|
87fbb8ec98 | ||
|
|
0d92d4ba61 | ||
|
|
b0df93bbcb | ||
|
|
290d0b226a | ||
|
|
8b3469610c | ||
|
|
50b47fb73b | ||
|
|
5334cb8688 | ||
|
|
38983df42d | ||
|
|
df963cb71c | ||
|
|
e9368fb04e | ||
|
|
e2a1630cf4 | ||
|
|
4f15b7c9fa | ||
|
|
63f500ad7f | ||
|
|
a9fb4546e1 | ||
|
|
cabbbf7f02 | ||
|
|
59324b0082 | ||
|
|
6a356c82a5 | ||
|
|
70f0f5714a | ||
|
|
07b527a0f2 | ||
|
|
80aa75aab1 | ||
|
|
0cf4211aa5 | ||
|
|
1de02a5099 | ||
|
|
bb1cecb95b | ||
|
|
d82397a173 | ||
|
|
856cf5e568 | ||
|
|
9f5a6ee549 | ||
|
|
9f3f644b83 | ||
|
|
a2f0837d14 | ||
|
|
c7f6889534 | ||
|
|
0415326d09 | ||
|
|
16a0f8ece0 | ||
|
|
5d1ef296b3 | ||
|
|
16dbcde90b | ||
|
|
50cbf25c72 | ||
|
|
7b87de2b4c | ||
|
|
1ce54a7925 | ||
|
|
1bfe7dd99b | ||
|
|
27e855ddbd | ||
|
|
3d1bed0f8f | ||
|
|
5c9ea9b63a | ||
|
|
7c034f5670 | ||
|
|
3b9f5a417a | ||
|
|
cde501af8d | ||
|
|
3c5592c1c8 | ||
|
|
2508e022bb | ||
|
|
01fcbc24e8 | ||
|
|
204e639679 | ||
|
|
3d301ec730 | ||
|
|
9ab6d57019 | ||
|
|
37c473130f | ||
|
|
5f95987a48 | ||
|
|
d530b34073 | ||
|
|
35dec7a5ec | ||
|
|
baedad8124 | ||
|
|
007378c3a6 | ||
|
|
beae9fd6ec | ||
|
|
b7507076c6 | ||
|
|
6b5ade3ca0 | ||
|
|
715192d26c | ||
|
|
ce140460af | ||
|
|
d30b0403ce | ||
|
|
255c993548 | ||
|
|
557ae4165c | ||
|
|
a31395ed80 | ||
|
|
397886d289 | ||
|
|
7307bec2ae | ||
|
|
0cd5147e1a | ||
|
|
36d5b092d7 | ||
|
|
f9014dbab3 | ||
|
|
755d5f77ea | ||
|
|
906d9af7b7 | ||
|
|
14dcb37ee1 | ||
|
|
c1c2a27358 | ||
|
|
5ab9657f9c | ||
|
|
7a78f9f5aa | ||
|
|
ac8c65f062 | ||
|
|
1954a9f3f8 | ||
|
|
3b764f9c90 | ||
|
|
10f55cc549 | ||
|
|
cd8d955646 | ||
|
|
bba07c9080 | ||
|
|
dba84a33b9 | ||
|
|
ae49166aa2 | ||
|
|
e09185fd0e | ||
|
|
56379bb3b9 | ||
|
|
027e4b4f25 | ||
|
|
ba951cb6e3 | ||
|
|
ae85cf4b6c | ||
|
|
dbc79f8c42 | ||
|
|
54c3070607 | ||
|
|
013eaa30b6 | ||
|
|
751043bf81 | ||
|
|
14f7198a07 | ||
|
|
94af819ae5 | ||
|
|
dbcc9afbc7 | ||
|
|
8556033ae6 | ||
|
|
650493f863 | ||
|
|
d80ad77871 | ||
|
|
f4b129b9f1 | ||
|
|
c0a05e0650 | ||
|
|
33d95d3e3a | ||
|
|
f573f83fb9 | ||
|
|
e94c36b7e6 | ||
|
|
c879e9e34d | ||
|
|
ac39b564a8 | ||
|
|
d91388aba4 | ||
|
|
733d78abdd | ||
|
|
d5809e375c | ||
|
|
2440a676bd | ||
|
|
03ac6c72e7 | ||
|
|
1bbbcabae0 | ||
|
|
9149b6b998 | ||
|
|
2603b5a402 | ||
|
|
dbddf5b9eb | ||
|
|
841f77bac2 | ||
|
|
83ffe75baa | ||
|
|
8cb7094803 | ||
|
|
ed8cd0ad19 | ||
|
|
90d8e65a3b | ||
|
|
b24fcb18af | ||
|
|
c2f2d0f8af | ||
|
|
e33bdd7e62 | ||
|
|
402adc3559 | ||
|
|
0f45d03c51 | ||
|
|
0397d7ab53 | ||
|
|
79f86b82e4 | ||
|
|
261a7a34e3 | ||
|
|
723bb89e10 | ||
|
|
832e4f3c37 | ||
|
|
75a4081549 | ||
|
|
f9291f9fd1 | ||
|
|
c3b4ee9321 | ||
|
|
f86896943d | ||
|
|
c33f05e8ca | ||
|
|
52727ded03 | ||
|
|
f7d132758e | ||
|
|
bb17ca9a53 | ||
|
|
aab21c5b17 | ||
|
|
acbafee02a | ||
|
|
c6d2b1a222 | ||
|
|
b037f75fb0 | ||
|
|
a1e79d3050 | ||
|
|
354969d5fa | ||
|
|
a371892409 | ||
|
|
b0789a7ce7 | ||
|
|
08be8eb4f8 | ||
|
|
bafddf4baf | ||
|
|
75b9184a00 | ||
|
|
5dc83cf2bf | ||
|
|
092e9062c8 | ||
|
|
512c921a81 | ||
|
|
defcd6fe26 | ||
|
|
025b6cbfb7 | ||
|
|
b0687dbeb5 | ||
|
|
e0b109cba6 | ||
|
|
adaa8ece89 | ||
|
|
6516b20e16 | ||
|
|
839cb03690 | ||
|
|
2bcd99b14f | ||
|
|
e3ebf6e8a1 | ||
|
|
76d28314b0 | ||
|
|
ec450b8fd8 | ||
|
|
79c5b2edd5 | ||
|
|
2d45ac51ef | ||
|
|
505bb8f06d | ||
|
|
f8408bd29f | ||
|
|
5f2c84a913 | ||
|
|
3011c99e3f | ||
|
|
ebc97f42ad | ||
|
|
4660c6d363 | ||
|
|
e239ef50ba | ||
|
|
8b4312a880 | ||
|
|
90daf8087e | ||
|
|
dd21bcb34c | ||
|
|
c4113f1ac7 | ||
|
|
efa48acd1d | ||
|
|
15e4d07a6d | ||
|
|
cb2248809c | ||
|
|
eb9551d81b | ||
|
|
87d1256a1b | ||
|
|
dd6179cf25 | ||
|
|
23c56ff887 | ||
|
|
c4eefa6917 | ||
|
|
202cff58f2 | ||
|
|
025806f0fd | ||
|
|
b0c54ef0f1 | ||
|
|
4d7681b1a4 | ||
|
|
340fb3f624 | ||
|
|
a83aad22ca | ||
|
|
5a418dcce6 | ||
|
|
ec5392708f | ||
|
|
901db92b11 | ||
|
|
01b8b10344 | ||
|
|
698d642ec8 | ||
|
|
90d1047fb2 | ||
|
|
b0d1eac477 | ||
|
|
cce02aec3d | ||
|
|
492ff58aa8 | ||
|
|
dd3e73996b | ||
|
|
931ed7adac | ||
|
|
861fd55d06 | ||
|
|
9a4eee4e7d | ||
|
|
ed76cdbddf | ||
|
|
9d91549803 | ||
|
|
a5425a3c71 | ||
|
|
f4b105b10f | ||
|
|
e4de09c55b | ||
|
|
d77be9d382 | ||
|
|
626909addb | ||
|
|
9b750bedef | ||
|
|
b976e0ef4e | ||
|
|
fd434292ad | ||
|
|
7b4d3a869b | ||
|
|
eeebb1b59f | ||
|
|
63136f64b7 | ||
|
|
1d2fbf2d92 | ||
|
|
1e52dded14 | ||
|
|
cfc7005275 | ||
|
|
f23afcd5aa | ||
|
|
4e88a0c91b | ||
|
|
d070f9deb0 | ||
|
|
b736e20a74 | ||
|
|
aad20d0a03 | ||
|
|
7ff97348d9 | ||
|
|
68dda3a46d | ||
|
|
2cd44f8c33 | ||
|
|
9775954aff | ||
|
|
1a071b0b54 | ||
|
|
8dcea59c74 | ||
|
|
f482f77871 | ||
|
|
b058c39ee1 | ||
|
|
b926b6c67f | ||
|
|
3fb8e5f799 | ||
|
|
277ccb5188 | ||
|
|
9ebc9c0867 | ||
|
|
f1f96713a4 | ||
|
|
fc3b6d2c2e | ||
|
|
d0d0716b3b | ||
|
|
73119afeff | ||
|
|
8939179be8 | ||
|
|
adba2e68db | ||
|
|
0ef8b471a3 | ||
|
|
205950fc5f | ||
|
|
8835b2c745 | ||
|
|
74fda40764 | ||
|
|
687a36937e | ||
|
|
2c7b8bd6e8 | ||
|
|
e9417f5fa1 | ||
|
|
5e08b34c43 | ||
|
|
7b436ffb3b | ||
|
|
1ee2ec3728 | ||
|
|
ed28768146 | ||
|
|
f931835176 | ||
|
|
0cf9bc2814 | ||
|
|
8b428f2c93 | ||
|
|
10238dbcd3 | ||
|
|
6229e0928d | ||
|
|
5c7b259fe9 | ||
|
|
cc84c867c0 | ||
|
|
5bf252e12d | ||
|
|
75512ff66a | ||
|
|
6f4832476a | ||
|
|
86b0d27299 | ||
|
|
5a8845f7f6 | ||
|
|
709e47f32f | ||
|
|
77590b4eb3 | ||
|
|
72fc313135 | ||
|
|
39b32cee2e | ||
|
|
bdcee7c052 | ||
|
|
4093e53b5b | ||
|
|
a4c1c8de24 | ||
|
|
7ed234c875 | ||
|
|
0359160ac6 | ||
|
|
2478dad9b5 | ||
|
|
690292352b | ||
|
|
271d18cddc | ||
|
|
e1465639e7 | ||
|
|
ce7ca59339 | ||
|
|
76610b25d7 | ||
|
|
dfce0bda7c | ||
|
|
41c0dd9727 | ||
|
|
232c0389d3 | ||
|
|
d95c8a4ab0 | ||
|
|
374fdb37e1 | ||
|
|
f78530636e | ||
|
|
0bf81f4fb9 | ||
|
|
dcc3b7f36b | ||
|
|
d6722266f5 | ||
|
|
11566891dc | ||
|
|
9aaf69cc9a | ||
|
|
a716a59489 | ||
|
|
bad0d1bbcf | ||
|
|
aa43e265b7 | ||
|
|
67280951ff | ||
|
|
c3a9f6f9f5 | ||
|
|
e631e46dd1 | ||
|
|
15163ffde0 | ||
|
|
b898284821 | ||
|
|
3bb7eb2e03 | ||
|
|
11fcb9d456 | ||
|
|
29f826448a | ||
|
|
a8cf4a7120 | ||
|
|
60dce94a47 | ||
|
|
c965b9cc24 | ||
|
|
762a32eb6d | ||
|
|
541dac1aee | ||
|
|
e2e2329301 | ||
|
|
9afad71b0f | ||
|
|
7bbe0f7e8a | ||
|
|
d90adfa98e | ||
|
|
1dbcc4b776 | ||
|
|
18696fca2d | ||
|
|
c40100b6da | ||
|
|
6396818740 | ||
|
|
6df5a0d47b | ||
|
|
15c18c5547 | ||
|
|
4b6981c2e7 | ||
|
|
1b4025300c | ||
|
|
983c871bff | ||
|
|
609f532f8c | ||
|
|
c6fc03c73a | ||
|
|
b6e48cc4f9 | ||
|
|
50f43cc178 | ||
|
|
f421067a0d | ||
|
|
edd9a2d5b6 | ||
|
|
41e0329f55 | ||
|
|
21ea916e0d | ||
|
|
3b6ca3020e | ||
|
|
3737845b78 | ||
|
|
a30c78cd12 | ||
|
|
f8fba41a30 | ||
|
|
052902fb49 | ||
|
|
58143c26bc | ||
|
|
5d83894056 | ||
|
|
e35667525f | ||
|
|
2f318152d8 | ||
|
|
bc518a9ae8 | ||
|
|
425ae2d536 | ||
|
|
a6cacd4aba | ||
|
|
5a7083537c | ||
|
|
e15f7a59fd | ||
|
|
a2fa526aa0 | ||
|
|
7e959d6a87 | ||
|
|
5121fe1cbf | ||
|
|
3c3d4fc151 | ||
|
|
a7f75c9a6c | ||
|
|
e7262b8fbe | ||
|
|
af3099c526 | ||
|
|
2b9d47cea8 | ||
|
|
5db90d3fc4 | ||
|
|
372d5ff758 | ||
|
|
ebf39eaea1 | ||
|
|
556786f2e1 | ||
|
|
0f64994537 | ||
|
|
ac64c2022b | ||
|
|
9802132b6f | ||
|
|
4d6c5c14f1 | ||
|
|
d228a5fb93 | ||
|
|
7b46ef10c8 | ||
|
|
8eb9fba051 | ||
|
|
7b58182683 | ||
|
|
95fbf9274b | ||
|
|
09557dfa0f | ||
|
|
4029fcc1ca | ||
|
|
d6627b1e34 | ||
|
|
86d75fd767 | ||
|
|
e2220bb3b3 | ||
|
|
1a9b8bd1da | ||
|
|
9eda2d3f77 | ||
|
|
e6d59df705 | ||
|
|
db845850b2 | ||
|
|
d516597659 | ||
|
|
3af5a8145a | ||
|
|
31bebd4a7a | ||
|
|
ccb87258b0 | ||
|
|
2ab71e88bd | ||
|
|
78bd7585bb | ||
|
|
92cc81d9b8 | ||
|
|
97a1c741de | ||
|
|
077d693959 | ||
|
|
94831fc10a | ||
|
|
1f298a88b0 | ||
|
|
7e49946bed | ||
|
|
1e81ab1017 | ||
|
|
311180d12e | ||
|
|
0efb206881 | ||
|
|
0b92fa5615 | ||
|
|
a58a5b56b2 | ||
|
|
b9764c0a44 | ||
|
|
590f7ba511 | ||
|
|
449909b0e8 | ||
|
|
40780525f8 | ||
|
|
0e3707d1c3 | ||
|
|
8ddbef093b | ||
|
|
4ccdfccdf0 | ||
|
|
3c8aa0c630 | ||
|
|
ba519f996a | ||
|
|
62d9b92e6e | ||
|
|
d2c909584d | ||
|
|
219916eb14 | ||
|
|
0a37ac901f | ||
|
|
4586baea27 | ||
|
|
d83961e85b | ||
|
|
7e35716ff0 | ||
|
|
d0cf1ac605 | ||
|
|
9a19d07ab8 | ||
|
|
922be0b164 | ||
|
|
d0b8e2e37e | ||
|
|
e3d6e08b6a | ||
|
|
16a6623095 | ||
|
|
7bf31ca149 | ||
|
|
030f2360ca | ||
|
|
08eafc4214 | ||
|
|
134ece9385 | ||
|
|
3e4b06e959 | ||
|
|
3e3c6f70ba | ||
|
|
3097378a10 | ||
|
|
53f7a0f78a | ||
|
|
45a6841772 | ||
|
|
80b93a6e33 | ||
|
|
6aaab641be | ||
|
|
4999490c06 | ||
|
|
c7c1cd8bb3 | ||
|
|
8a1f116305 | ||
|
|
f8fe1dda6d | ||
|
|
bf44232d5c | ||
|
|
8c8ba47ef9 | ||
|
|
b3580002d0 | ||
|
|
1249199b22 | ||
|
|
f39a47f354 | ||
|
|
f58f15925f | ||
|
|
a071f8bb86 | ||
|
|
d33609ee57 | ||
|
|
f2c08bc1e8 | ||
|
|
688d8ed7bc | ||
|
|
2ddb4018b8 | ||
|
|
3ec25683f7 | ||
|
|
25d426f483 | ||
|
|
9d91ebc47a | ||
|
|
c784ab6632 | ||
|
|
ed5e3f13a1 | ||
|
|
3dcd82745e | ||
|
|
c564dc5f29 | ||
|
|
d64453b661 | ||
|
|
834ed7db0e | ||
|
|
db1dde533f | ||
|
|
9c66d9465e | ||
|
|
8c193d004e | ||
|
|
7cbd7f999a | ||
|
|
4340c8cb00 | ||
|
|
6f6583772d | ||
|
|
c62bc8d5da | ||
|
|
f68bfcb3e2 | ||
|
|
a37ade13cd | ||
|
|
1e0129f2d8 | ||
|
|
2e1d4381b0 | ||
|
|
a409b4f49c | ||
|
|
926776204b | ||
|
|
bba490127d | ||
|
|
80672c43c0 | ||
|
|
926e0ea0e5 | ||
|
|
6da169cd56 | ||
|
|
aaf10aa118 | ||
|
|
145bdacf13 | ||
|
|
51309efd46 | ||
|
|
60fe143b07 | ||
|
|
3f921b69f6 | ||
|
|
d2ac81d7ba | ||
|
|
2e5a9479a8 | ||
|
|
ec664ab6a2 | ||
|
|
8818bf8cf0 | ||
|
|
cc53e0c8ff | ||
|
|
8353499d18 | ||
|
|
d2c5994616 | ||
|
|
500b9097f7 | ||
|
|
7993266e6e | ||
|
|
74090103a9 | ||
|
|
a18cde2340 | ||
|
|
ee98e97876 | ||
|
|
ff63bafd72 | ||
|
|
3f8c8be77a | ||
|
|
769cdc73e7 | ||
|
|
cef8f74c00 | ||
|
|
9f5ab709de | ||
|
|
c6fdae3b3c | ||
|
|
320cf0fea2 | ||
|
|
0261f1262f | ||
|
|
5278ae3662 | ||
|
|
2941c44de2 | ||
|
|
627222602e | ||
|
|
e13b1ffc48 | ||
|
|
10bafce217 | ||
|
|
4817969495 | ||
|
|
2feda55eb7 | ||
|
|
a74cfd453a | ||
|
|
a360f65133 | ||
|
|
6a903d65a7 | ||
|
|
d4b3166036 | ||
|
|
21a54e2333 | ||
|
|
37c58bffba | ||
|
|
4a42b7277c | ||
|
|
071aea397b | ||
|
|
9c02f918c1 | ||
|
|
15c5c9615e | ||
|
|
0b74692d62 | ||
|
|
8f24f55eb7 | ||
|
|
cd5ab1ae9b | ||
|
|
d29ea97948 | ||
|
|
9930e7bb93 | ||
|
|
b1d37e4848 | ||
|
|
893152cdf3 | ||
|
|
efbf98751d | ||
|
|
caac294e79 | ||
|
|
d145ad8f47 | ||
|
|
628034ae8c | ||
|
|
fee02a3d16 | ||
|
|
ce5ae13bf6 | ||
|
|
26b6a94e32 | ||
|
|
be6ef475ba | ||
|
|
55e218ac37 | ||
|
|
7d1f636cdd | ||
|
|
a4b8b9b09b | ||
|
|
4e8e28d27c | ||
|
|
4b52414435 | ||
|
|
811b96bcbe | ||
|
|
f3207855ca | ||
|
|
9f3c5b93e3 | ||
|
|
a56357f0c1 | ||
|
|
f8d14d2e56 | ||
|
|
b0c30759c8 | ||
|
|
54037e6e10 | ||
|
|
fc260d4a37 | ||
|
|
387d4e5bc9 | ||
|
|
4ffd46b391 | ||
|
|
3b49370c06 | ||
|
|
925d26e54c | ||
|
|
1283006b53 | ||
|
|
83a718c9db | ||
|
|
2abf03ccb7 | ||
|
|
a59810a487 | ||
|
|
9cc9e06ad1 | ||
|
|
0108a0c146 | ||
|
|
4188758d84 | ||
|
|
2144100f81 | ||
|
|
8a61e04be6 | ||
|
|
eaeb083891 | ||
|
|
25e117b412 | ||
|
|
6b7ceed1a5 | ||
|
|
0533fc98a2 | ||
|
|
edde3ab2fb | ||
|
|
ec20e518be | ||
|
|
930a582afa | ||
|
|
7536eeea54 | ||
|
|
d940d43907 | ||
|
|
3ad3dd9493 |
29
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
29
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal 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.
|
||||
12
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
12
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
# 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 clean compile` locally. This may reformat your code, commit those changes.
|
||||
- [ ] Run `mvn -D enable-ci clean install site` locally. If this command doesn't succeed, your change will not pass CI.
|
||||
|
||||
19
.github/release-drafter.yml
vendored
Normal file
19
.github/release-drafter.yml
vendored
Normal 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
|
||||
72
.github/workflows/maven-build.yml
vendored
Normal file
72
.github/workflows/maven-build.yml
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
name: CI
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: build-only (Java ${{ matrix.java }})
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
java: [ 13 ]
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up JDK
|
||||
uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: ${{ matrix.java }}
|
||||
- name: Cached .m2
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: ~/.m2/repository
|
||||
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-maven-
|
||||
- name: Maven Install (skipTests)
|
||||
run: mvn -B install -DskipTests -D enable-ci --file pom.xml
|
||||
site:
|
||||
name: site (Java ${{ matrix.java }})
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
java: [ 8, 11 ]
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up JDK
|
||||
uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: ${{ matrix.java }}
|
||||
- uses: actions/cache@v1
|
||||
with:
|
||||
path: ~/.m2/repository
|
||||
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-maven-
|
||||
- name: Maven Site
|
||||
run: mvn -B site -D enable-ci --file pom.xml
|
||||
test:
|
||||
name: test (${{ matrix.os }}, Java ${{ matrix.java }})
|
||||
runs-on: ${{ matrix.os }}-latest
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ ubuntu, windows ]
|
||||
java: [ 8, 11, 13, 15-ea ]
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up JDK
|
||||
uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: ${{ matrix.java }}
|
||||
- uses: actions/cache@v1
|
||||
with:
|
||||
path: ~/.m2/repository
|
||||
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-maven-
|
||||
- name: Maven Install without Code Coverage
|
||||
if: matrix.os == 'windows'
|
||||
run: mvn -B install --file pom.xml
|
||||
- name: Maven Install with Code Coverage
|
||||
if: matrix.os != 'windows'
|
||||
run: mvn -B install -D enable-ci --file pom.xml
|
||||
8
.gitignore
vendored
8
.gitignore
vendored
@@ -3,3 +3,11 @@ target
|
||||
*.iml
|
||||
*.ipr
|
||||
*.iws
|
||||
.classpath
|
||||
.project
|
||||
.settings/
|
||||
.DS_Store
|
||||
|
||||
dependency-reduced-pom.xml
|
||||
.factorypath
|
||||
.vscode/settings.json
|
||||
|
||||
1182
CHANGELOG.md
Normal file
1182
CHANGELOG.md
Normal file
File diff suppressed because it is too large
Load Diff
76
CODE_OF_CONDUCT.md
Normal file
76
CODE_OF_CONDUCT.md
Normal 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
62
CONTRIBUTING.md
Normal 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.
|
||||
22
LICENSE.txt
Normal file
22
LICENSE.txt
Normal file
@@ -0,0 +1,22 @@
|
||||
Copyright (c) 2011- Kohsuke Kawaguchi and other contributors
|
||||
|
||||
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.
|
||||
3
README
3
README
@@ -1,3 +0,0 @@
|
||||
Java API for GitHub
|
||||
|
||||
See http://github-api.kohsuke.org/ for more details
|
||||
9
README.md
Normal file
9
README.md
Normal file
@@ -0,0 +1,9 @@
|
||||
# Java API for GitHub
|
||||
|
||||
[](https://mvnrepository.com/artifact/org.kohsuke/github-api)
|
||||
[](https://gitter.im/hub4j/github-api?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||

|
||||
|
||||
|
||||
|
||||
See https://github-api.kohsuke.org/ for more details
|
||||
617
pom.xml
617
pom.xml
@@ -1,40 +1,316 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.kohsuke</groupId>
|
||||
<artifactId>pom</artifactId>
|
||||
<version>6</version>
|
||||
</parent>
|
||||
|
||||
<groupId>org.kohsuke</groupId>
|
||||
<artifactId>github-api</artifactId>
|
||||
<version>1.45</version>
|
||||
<version>1.112</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>
|
||||
<connection>scm:git:git@github.com/hub4j/${project.artifactId}.git</connection>
|
||||
<developerConnection>scm:git:ssh://git@github.com/hub4j/${project.artifactId}.git</developerConnection>
|
||||
<url>https://github.com/hub4j/github-api/</url>
|
||||
<tag>github-api-1.112</tag>
|
||||
</scm>
|
||||
|
||||
<distributionManagement>
|
||||
<snapshotRepository>
|
||||
<id>sonatype-nexus-snapshots</id>
|
||||
<name>Sonatype Nexus Snapshots</name>
|
||||
<url>https://oss.sonatype.org/content/repositories/snapshots/</url>
|
||||
</snapshotRepository>
|
||||
<repository>
|
||||
<id>sonatype-nexus-staging</id>
|
||||
<name>Nexus Release Repository</name>
|
||||
<url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
|
||||
</repository>
|
||||
<site>
|
||||
<id>github-pages</id>
|
||||
<url>gitsite:git@github.com/kohsuke/${project.artifactId}.git</url>
|
||||
<url>gitsite:git@github.com/hub4j/${project.artifactId}.git</url>
|
||||
</site>
|
||||
</distributionManagement>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<spotbugs-maven-plugin.version>4.0.0</spotbugs-maven-plugin.version>
|
||||
<spotbugs.version>4.0.3</spotbugs.version>
|
||||
<spotbugs-maven-plugin.failOnError>true</spotbugs-maven-plugin.failOnError>
|
||||
<hamcrest.version>2.2</hamcrest.version>
|
||||
<okhttp3.version>4.4.1</okhttp3.version>
|
||||
<okio.version>2.5.0</okio.version>
|
||||
<formatter-maven-plugin.goal>format</formatter-maven-plugin.goal>
|
||||
<impsort-maven-plugin.goal>sort</impsort-maven-plugin.goal>
|
||||
<!-- Using this as the minimum bar for code coverage. Adding methods without covering them will fail this. -->
|
||||
<jacoco.coverage.target.bundle.method>0.60</jacoco.coverage.target.bundle.method>
|
||||
<jacoco.coverage.target.class.method>0.25</jacoco.coverage.target.class.method>
|
||||
<!-- 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>
|
||||
<!-- Doing site publishing manually for now -->
|
||||
<!--
|
||||
<extension>
|
||||
<groupId>org.kohsuke</groupId>
|
||||
<artifactId>wagon-gitsite</artifactId>
|
||||
<version>0.3.5</version>
|
||||
</extension>
|
||||
-->
|
||||
</extensions>
|
||||
<testResources>
|
||||
<testResource>
|
||||
<directory>src/test/resources</directory>
|
||||
<excludes>
|
||||
<exclude>**/wiremock/**</exclude>
|
||||
</excludes>
|
||||
</testResource>
|
||||
</testResources>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-source-plugin</artifactId>
|
||||
<version>3.2.1</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-gpg-plugin</artifactId>
|
||||
<version>1.6</version>
|
||||
</plugin>
|
||||
<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>test</phase>
|
||||
<goals>
|
||||
<goal>check</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<rules>
|
||||
<rule>
|
||||
<element>BUNDLE</element>
|
||||
<limits>
|
||||
<limit>
|
||||
<counter>METHOD</counter>
|
||||
<value>COVEREDRATIO</value>
|
||||
<minimum>${jacoco.coverage.target.bundle.method}</minimum>
|
||||
</limit>
|
||||
</limits>
|
||||
</rule>
|
||||
<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>
|
||||
<limit>
|
||||
<counter>METHOD</counter>
|
||||
<value>COVEREDRATIO</value>
|
||||
<minimum>${jacoco.coverage.target.class.method}</minimum>
|
||||
</limit>
|
||||
</limits>
|
||||
<excludes>
|
||||
<!-- Code implemented externally -->
|
||||
<exclude>org.kohsuke.github.extras.okhttp3.ObsoleteUrlFactory.**</exclude>
|
||||
<exclude>org.kohsuke.github.extras.okhttp3.ObsoleteUrlFactory</exclude>
|
||||
|
||||
<!-- Sample only -->
|
||||
<exclude>org.kohsuke.github.example.*</exclude>
|
||||
|
||||
<!-- No methods -->
|
||||
<exclude>org.kohsuke.github.Previews</exclude>
|
||||
|
||||
<!-- Deprecated -->
|
||||
<exclude>org.kohsuke.github.extras.OkHttp3Connector</exclude>
|
||||
<exclude>org.kohsuke.github.EnforcementLevel</exclude>
|
||||
<exclude>org.kohsuke.github.GHPerson.1</exclude>
|
||||
|
||||
<!-- These fail coverage on windows because tests are disabled -->
|
||||
<exclude>org.kohsuke.github.GHAsset</exclude>
|
||||
<exclude>org.kohsuke.github.GHReleaseBuilder</exclude>
|
||||
<exclude>org.kohsuke.github.GHRelease</exclude>
|
||||
|
||||
<!-- TODO: These still need test coverage -->
|
||||
<exclude>org.kohsuke.github.GHBranchProtection.RequiredSignatures</exclude>
|
||||
<exclude>org.kohsuke.github.GHBranchProtectionBuilder.Restrictions</exclude>
|
||||
<exclude>org.kohsuke.github.GHBranchProtection.Restrictions</exclude>
|
||||
<exclude>org.kohsuke.github.GHCommentAuthorAssociation</exclude>
|
||||
<exclude>org.kohsuke.github.GHCommitBuilder.UserInfo</exclude>
|
||||
<exclude>org.kohsuke.github.GHCommitState</exclude>
|
||||
<exclude>org.kohsuke.github.GHCompare.Commit</exclude>
|
||||
<exclude>org.kohsuke.github.GHCompare.InnerCommit</exclude>
|
||||
<exclude>org.kohsuke.github.GHCompare.Status</exclude>
|
||||
<exclude>org.kohsuke.github.GHCompare.Tree</exclude>
|
||||
<exclude>org.kohsuke.github.GHCompare.User</exclude>
|
||||
<exclude>org.kohsuke.github.GHCompare</exclude>
|
||||
<exclude>org.kohsuke.github.GHDeployKey</exclude>
|
||||
<exclude>org.kohsuke.github.GHDeploymentStatusBuilder</exclude>
|
||||
<exclude>org.kohsuke.github.GHDirection</exclude>
|
||||
<exclude>org.kohsuke.github.GHEmail</exclude>
|
||||
<exclude>org.kohsuke.github.GHEventPayload.Ping</exclude>
|
||||
<exclude>org.kohsuke.github.GHEventPayload.Release</exclude>
|
||||
<exclude>org.kohsuke.github.GHException</exclude>
|
||||
<exclude>org.kohsuke.github.GHHook</exclude>
|
||||
<exclude>org.kohsuke.github.GHHooks.OrgContext</exclude>
|
||||
<exclude>org.kohsuke.github.GHInvitation</exclude>
|
||||
<exclude>org.kohsuke.github.GHMilestoneState</exclude>
|
||||
<exclude>org.kohsuke.github.GHOrgHook</exclude>
|
||||
<exclude>org.kohsuke.github.GHProject.ProjectStateFilter</exclude>
|
||||
<exclude>org.kohsuke.github.GHPullRequestCommitDetail.Authorship</exclude>
|
||||
<exclude>org.kohsuke.github.GHPullRequestCommitDetail.Commit</exclude>
|
||||
<exclude>org.kohsuke.github.GHPullRequestCommitDetail.CommitPointer</exclude>
|
||||
<exclude>org.kohsuke.github.GHPullRequestCommitDetail.Tree</exclude>
|
||||
<exclude>org.kohsuke.github.GHPullRequestCommitDetail</exclude>
|
||||
<exclude>org.kohsuke.github.GHPullRequestFileDetail</exclude>
|
||||
<exclude>org.kohsuke.github.GHPullRequestQueryBuilder.Sort</exclude>
|
||||
<exclude>org.kohsuke.github.GHReleaseUpdater</exclude>
|
||||
<exclude>org.kohsuke.github.GHRepository.ForkSort</exclude>
|
||||
<exclude>org.kohsuke.github.GHRequestedAction</exclude>
|
||||
<exclude>org.kohsuke.github.GHStargazer</exclude>
|
||||
<exclude>org.kohsuke.github.GHTagObject</exclude>
|
||||
<exclude>org.kohsuke.github.GHTeam.Role</exclude>
|
||||
<exclude>org.kohsuke.github.GHUserSearchBuilder.Sort</exclude>
|
||||
<exclude>org.kohsuke.github.GHVerifiedKey</exclude>
|
||||
</excludes>
|
||||
</rule>
|
||||
</rules>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
<version>3.2.0</version>
|
||||
<configuration>
|
||||
<source>8</source>
|
||||
<failOnWarnings>true</failOnWarnings>
|
||||
<doclint>all</doclint>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.sonatype.plugins</groupId>
|
||||
<artifactId>nexus-staging-maven-plugin</artifactId>
|
||||
<version>1.6.8</version>
|
||||
<extensions>true</extensions>
|
||||
<configuration>
|
||||
<serverId>sonatype-nexus-staging</serverId>
|
||||
<nexusUrl>https://oss.sonatype.org/</nexusUrl>
|
||||
<autoReleaseAfterClose>true</autoReleaseAfterClose>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-site-plugin</artifactId>
|
||||
<version>3.9.0</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-release-plugin</artifactId>
|
||||
<version>2.5.3</version>
|
||||
<configuration>
|
||||
<autoVersionSubmodules>true</autoVersionSubmodules>
|
||||
<useReleaseProfile>false</useReleaseProfile>
|
||||
<releaseProfiles>release</releaseProfiles>
|
||||
<goals>deploy</goals>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.sonatype.plugins</groupId>
|
||||
<artifactId>nexus-staging-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-project-info-reports-plugin</artifactId>
|
||||
<version>3.1.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>
|
||||
<configuration>
|
||||
<!-- SUREFIRE-1226 workaround -->
|
||||
<trimStackTrace>false</trimStackTrace>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>animal-sniffer-maven-plugin</artifactId>
|
||||
<version>1.18</version>
|
||||
<configuration>
|
||||
<signature>
|
||||
<groupId>org.codehaus.mojo.signature</groupId>
|
||||
<artifactId>java18</artifactId>
|
||||
<version>1.0</version>
|
||||
</signature>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>ensure-java-1.8-class-library</id>
|
||||
<phase>test</phase>
|
||||
<goals>
|
||||
<goal>check</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>com.infradna.tool</groupId>
|
||||
<artifactId>bridge-method-injector</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.18</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
@@ -43,42 +319,135 @@
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<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.4.1</version>
|
||||
<configuration>
|
||||
<groups>*,java.,javax.</groups>
|
||||
<removeUnused>true</removeUnused>
|
||||
<staticAfter>true</staticAfter>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<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>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<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>
|
||||
<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>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>3.8.1</version>
|
||||
<version>4.13</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
<version>2.2.3</version>
|
||||
<version>2.10.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<version>1.4</version>
|
||||
<version>2.4</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.infradna.tool</groupId>
|
||||
<artifactId>bridge-method-annotation</artifactId>
|
||||
<version>1.4</version>
|
||||
<version>1.18</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<!-- for stapler-jetty -->
|
||||
<dependency>
|
||||
<groupId>commons-fileupload</groupId>
|
||||
<artifactId>commons-fileupload</artifactId>
|
||||
<version>1.4</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<!-- for stapler-jetty -->
|
||||
<dependency>
|
||||
<groupId>commons-discovery</groupId>
|
||||
<artifactId>commons-discovery</artifactId>
|
||||
<version>0.5</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<!-- for stapler-jetty -->
|
||||
<dependency>
|
||||
<groupId>org.kohsuke.stapler</groupId>
|
||||
<artifactId>stapler</artifactId>
|
||||
<version>1.259</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.kohsuke.stapler</groupId>
|
||||
<artifactId>stapler-jetty</artifactId>
|
||||
@@ -88,23 +457,219 @@
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jgit</groupId>
|
||||
<artifactId>org.eclipse.jgit</artifactId>
|
||||
<version>3.1.0.201310021548-r</version>
|
||||
<version>5.7.0.202003110725-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>org.kohsuke</groupId>
|
||||
<artifactId>wordnet-random-name</artifactId>
|
||||
<version>1.3</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-core</artifactId>
|
||||
<version>3.3.3</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.spotbugs</groupId>
|
||||
<artifactId>spotbugs-annotations</artifactId>
|
||||
<version>${spotbugs.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.tomakehurst</groupId>
|
||||
<artifactId>wiremock-jre8-standalone</artifactId>
|
||||
<version>2.26.3</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>https://repo.jenkins-ci.org/public/</url>
|
||||
</pluginRepository>
|
||||
</pluginRepositories>
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>ci-non-windows</id>
|
||||
<activation>
|
||||
<property>
|
||||
<name>enable-ci</name>
|
||||
</property>
|
||||
<os>
|
||||
<family>!windows</family>
|
||||
</os>
|
||||
</activation>
|
||||
<properties>
|
||||
<formatter-maven-plugin.goal>validate</formatter-maven-plugin.goal>
|
||||
<impsort-maven-plugin.goal>check</impsort-maven-plugin.goal>
|
||||
</properties>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>ci-all</id>
|
||||
<activation>
|
||||
<property>
|
||||
<name>enable-ci</name>
|
||||
</property>
|
||||
</activation>
|
||||
<properties>
|
||||
<jacoco.haltOnFailure>true</jacoco.haltOnFailure>
|
||||
</properties>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.jacoco</groupId>
|
||||
<artifactId>jacoco-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>release</id>
|
||||
<properties>
|
||||
<formatter-maven-plugin.goal>validate</formatter-maven-plugin.goal>
|
||||
<impsort-maven-plugin.goal>check</impsort-maven-plugin.goal>
|
||||
</properties>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.jacoco</groupId>
|
||||
<artifactId>jacoco-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-gpg-plugin</artifactId>
|
||||
<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>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>attach-sources</id>
|
||||
<goals>
|
||||
<goal>jar-no-fork</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>attach-javadocs</id>
|
||||
<goals>
|
||||
<goal>jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
<reporting>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.jacoco</groupId>
|
||||
<artifactId>jacoco-maven-plugin</artifactId>
|
||||
<reportSets>
|
||||
<reportSet>
|
||||
<reports>
|
||||
<!-- select non-aggregate reports -->
|
||||
<report>report</report>
|
||||
</reports>
|
||||
</reportSet>
|
||||
</reportSets>
|
||||
</plugin>
|
||||
<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>https://www.opensource.org/licenses/mit-license.php</url>
|
||||
<distribution>repo</distribution>
|
||||
</license>
|
||||
</licenses>
|
||||
|
||||
<mailingLists>
|
||||
<mailingList>
|
||||
<name>User List</name>
|
||||
<post>github-api@googlegroups.com</post>
|
||||
<archive>https://groups.google.com/forum/#!forum/github-api</archive>
|
||||
</mailingList>
|
||||
</mailingLists>
|
||||
|
||||
<developers>
|
||||
<developer>
|
||||
<name>Kohsuke Kawaguchi</name>
|
||||
<id>kohsuke</id>
|
||||
<email>kk@kohsuke.org</email>
|
||||
</developer>
|
||||
</developers>
|
||||
|
||||
</project>
|
||||
|
||||
165
src/main/java/org/kohsuke/github/AbstractBuilder.java
Normal file
165
src/main/java/org/kohsuke/github/AbstractBuilder.java
Normal file
@@ -0,0 +1,165 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.annotation.CheckForNull;
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
/**
|
||||
* An abstract data object builder/updater.
|
||||
*
|
||||
* This class can be use to make a Builder that supports both batch and single property changes.
|
||||
* <p>
|
||||
* Batching looks like this:
|
||||
* </p>
|
||||
*
|
||||
* <pre>
|
||||
* update().someName(value).otherName(value).done()
|
||||
* </pre>
|
||||
* <p>
|
||||
* Single changes look like this:
|
||||
* </p>
|
||||
*
|
||||
* <pre>
|
||||
* set().someName(value);
|
||||
* set().otherName(value);
|
||||
* </pre>
|
||||
* <p>
|
||||
* If {@link S} is the same as {@link R}, {@link #with(String, Object)} will commit changes after the first value change
|
||||
* and return a {@link R} from {@link #done()}.
|
||||
* </p>
|
||||
* <p>
|
||||
* If {@link S} is not the same as {@link R}, {@link #with(String, Object)} will batch together multiple changes and let
|
||||
* the user call {@link #done()} when they are ready.
|
||||
*
|
||||
* @param <R>
|
||||
* Final return type built by this builder returned when {@link #done()}} is called.
|
||||
* @param <S>
|
||||
* Intermediate return type for this builder returned by calls to {@link #with(String, Object)}. If {@link S}
|
||||
* the same as {@link R}, this builder will commit changes after each call to {@link #with(String, Object)}.
|
||||
*/
|
||||
abstract class AbstractBuilder<R, S> {
|
||||
|
||||
@Nonnull
|
||||
private final Class<R> returnType;
|
||||
|
||||
private final boolean commitChangesImmediately;
|
||||
|
||||
@CheckForNull
|
||||
private final R baseInstance;
|
||||
|
||||
@Nonnull
|
||||
protected final Requester requester;
|
||||
|
||||
// TODO: Not sure how update-in-place behavior should be controlled
|
||||
// However, it certainly can be controlled dynamically down to the instance level or inherited for all children of
|
||||
// some
|
||||
// connection.
|
||||
protected boolean updateInPlace;
|
||||
|
||||
/**
|
||||
* Creates a builder.
|
||||
*
|
||||
* @param root
|
||||
* the GitHub instance to connect to.
|
||||
* @param intermediateReturnType
|
||||
* the intermediate return type of type {@link S} returned by calls to {@link #with(String, Object)}.
|
||||
* Must either be equal to {@code builtReturnType} or this instance must be castable to this class. If
|
||||
* not, the constructor will throw {@link IllegalArgumentException}.
|
||||
* @param finalReturnType
|
||||
* the final return type for built by this builder returned when {@link #done()}} is called.
|
||||
* @param baseInstance
|
||||
* optional instance on which to base this builder.
|
||||
*/
|
||||
protected AbstractBuilder(@Nonnull Class<R> finalReturnType,
|
||||
@Nonnull Class<S> intermediateReturnType,
|
||||
@Nonnull GitHub root,
|
||||
@CheckForNull R baseInstance) {
|
||||
this.requester = root.createRequest();
|
||||
this.returnType = finalReturnType;
|
||||
this.commitChangesImmediately = returnType.equals(intermediateReturnType);
|
||||
if (!commitChangesImmediately && !intermediateReturnType.isInstance(this)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Argument \"intermediateReturnType\": This instance must be castable to intermediateReturnType or finalReturnType must be equal to intermediateReturnType.");
|
||||
}
|
||||
|
||||
this.baseInstance = baseInstance;
|
||||
this.updateInPlace = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finishes an update, committing changes.
|
||||
*
|
||||
* This method may update-in-place or not. Either way it returns the resulting instance.
|
||||
*
|
||||
* @return an instance with updated current data
|
||||
* @throws IOException
|
||||
* if there is an I/O Exception
|
||||
*/
|
||||
@Nonnull
|
||||
@Preview
|
||||
@Deprecated
|
||||
public R done() throws IOException {
|
||||
R result;
|
||||
if (updateInPlace && baseInstance != null) {
|
||||
result = requester.fetchInto(baseInstance);
|
||||
} else {
|
||||
result = requester.fetch(returnType);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies a value to a name for this builder.
|
||||
*
|
||||
* If {@link S} is the same as {@link R}, this method will commit changes after the first value change and return a
|
||||
* {@link R} from {@link #done()}.
|
||||
*
|
||||
* If {@link S} is not the same as {@link R}, this method will return an {@link S} and letting the caller batch
|
||||
* together multiple changes and call {@link #done()} when they are ready.
|
||||
*
|
||||
* @param name
|
||||
* the name of the field
|
||||
* @param value
|
||||
* the value of the field
|
||||
* @return either a continuing builder or an updated data record
|
||||
* @throws IOException
|
||||
* if an I/O error occurs
|
||||
*/
|
||||
@Nonnull
|
||||
@Preview
|
||||
@Deprecated
|
||||
protected S with(@Nonnull String name, Object value) throws IOException {
|
||||
requester.with(name, value);
|
||||
return continueOrDone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Chooses whether to return a continuing builder or an updated data record
|
||||
*
|
||||
* If {@link S} is the same as {@link R}, this method will commit changes after the first value change and return a
|
||||
* {@link R} from {@link #done()}.
|
||||
*
|
||||
* If {@link S} is not the same as {@link R}, this method will return an {@link S} and letting the caller batch
|
||||
* together multiple changes and call {@link #done()} when they are ready.
|
||||
*
|
||||
* @return either a continuing builder or an updated data record
|
||||
* @throws IOException
|
||||
* if an I/O error occurs
|
||||
*/
|
||||
@Nonnull
|
||||
@Preview
|
||||
@Deprecated
|
||||
protected S continueOrDone() throws IOException {
|
||||
// This little bit of roughness in this base class means all inheriting builders get to create Updater and
|
||||
// Setter classes from almost identical code. Creator can often be implemented with significant code reuse as
|
||||
// well.
|
||||
if (commitChangesImmediately) {
|
||||
// These casts look strange and risky, but they they're actually guaranteed safe due to the return path
|
||||
// being based on the previous comparison of class instances passed to the constructor.
|
||||
return (S) done();
|
||||
} else {
|
||||
return (S) this;
|
||||
}
|
||||
}
|
||||
}
|
||||
70
src/main/java/org/kohsuke/github/AbuseLimitHandler.java
Normal file
70
src/main/java/org/kohsuke/github/AbuseLimitHandler.java
Normal file
@@ -0,0 +1,70 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InterruptedIOException;
|
||||
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) GitHubBuilder#withAbuseLimitHandler(AbuseLimitHandler)
|
||||
* @see <a href="https://developer.github.com/v3/#abuse-rate-limits">documentation</a>
|
||||
* @see RateLimitHandler
|
||||
*/
|
||||
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.
|
||||
*
|
||||
* @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).
|
||||
* @param uc
|
||||
* 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>
|
||||
* @see <a href=
|
||||
* "https://developer.github.com/v3/guides/best-practices-for-integrators/#dealing-with-abuse-rate-limits">Dealing
|
||||
* with abuse rate limits</a>
|
||||
*
|
||||
*/
|
||||
public abstract void onError(IOException e, HttpURLConnection uc) throws IOException;
|
||||
|
||||
/**
|
||||
* Wait until the API abuse "wait time" is passed.
|
||||
*/
|
||||
public static final AbuseLimitHandler WAIT = new AbuseLimitHandler() {
|
||||
@Override
|
||||
public void onError(IOException e, HttpURLConnection uc) throws IOException {
|
||||
try {
|
||||
Thread.sleep(parseWaitTime(uc));
|
||||
} 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
|
||||
|
||||
return Math.max(1000, Long.parseLong(v) * 1000);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Fail immediately.
|
||||
*/
|
||||
public static final AbuseLimitHandler FAIL = new AbuseLimitHandler() {
|
||||
@Override
|
||||
public void onError(IOException e, HttpURLConnection uc) throws IOException {
|
||||
throw (IOException) new IOException("Abuse limit reached").initCause(e);
|
||||
}
|
||||
};
|
||||
}
|
||||
17
src/main/java/org/kohsuke/github/EnforcementLevel.java
Normal file
17
src/main/java/org/kohsuke/github/EnforcementLevel.java
Normal file
@@ -0,0 +1,17 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* This was added during preview API period but it has changed since then.
|
||||
*
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
@Deprecated
|
||||
public enum EnforcementLevel {
|
||||
OFF, NON_ADMINS, EVERYONE;
|
||||
|
||||
public String toString() {
|
||||
return name().toLowerCase(Locale.ENGLISH);
|
||||
}
|
||||
}
|
||||
293
src/main/java/org/kohsuke/github/GHApp.java
Normal file
293
src/main/java/org/kohsuke/github/GHApp.java
Normal file
@@ -0,0 +1,293 @@
|
||||
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
|
||||
* @deprecated Do not use this method. It was added due to incomplete understanding of Jackson binding.
|
||||
*/
|
||||
@Deprecated
|
||||
public void setOwner(GHUser owner) {
|
||||
this.owner = owner;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets name.
|
||||
*
|
||||
* @return the name
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets name.
|
||||
*
|
||||
* @param name
|
||||
* the name
|
||||
* @deprecated Do not use this method. It was added due to incomplete understanding of Jackson binding.
|
||||
*/
|
||||
@Deprecated
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets description.
|
||||
*
|
||||
* @return the description
|
||||
*/
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets description.
|
||||
*
|
||||
* @param description
|
||||
* the description
|
||||
* @deprecated Do not use this method. It was added due to incomplete understanding of Jackson binding.
|
||||
*/
|
||||
@Deprecated
|
||||
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
|
||||
* @deprecated Do not use this method. It was added due to incomplete understanding of Jackson binding.
|
||||
*/
|
||||
@Deprecated
|
||||
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
|
||||
* @deprecated Do not use this method. It was added due to incomplete understanding of Jackson binding.
|
||||
*/
|
||||
@Deprecated
|
||||
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
|
||||
* @deprecated Do not use this method. It was added due to incomplete understanding of Jackson binding.
|
||||
*/
|
||||
@Deprecated
|
||||
public void setInstallationsCount(long installationsCount) {
|
||||
this.installationsCount = installationsCount;
|
||||
}
|
||||
|
||||
public URL getHtmlUrl() {
|
||||
return GitHubClient.parseURL(htmlUrl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets permissions.
|
||||
*
|
||||
* @return the permissions
|
||||
*/
|
||||
public Map<String, String> getPermissions() {
|
||||
return permissions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets permissions.
|
||||
*
|
||||
* @param permissions
|
||||
* the permissions
|
||||
* @deprecated Do not use this method. It was added due to incomplete understanding of Jackson binding.
|
||||
*/
|
||||
@Deprecated
|
||||
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.createRequest()
|
||||
.withPreview(MACHINE_MAN)
|
||||
.withUrlPath("/app/installations")
|
||||
.toIterable(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.createRequest()
|
||||
.withPreview(MACHINE_MAN)
|
||||
.withUrlPath(String.format("/app/installations/%d", id))
|
||||
.fetch(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.createRequest()
|
||||
.withPreview(MACHINE_MAN)
|
||||
.withUrlPath(String.format("/orgs/%s/installation", name))
|
||||
.fetch(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.createRequest()
|
||||
.withPreview(MACHINE_MAN)
|
||||
.withUrlPath(String.format("/repos/%s/%s/installation", ownerName, repositoryName))
|
||||
.fetch(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.createRequest()
|
||||
.withPreview(MACHINE_MAN)
|
||||
.withUrlPath(String.format("/users/%s/installation", name))
|
||||
.fetch(GHAppInstallation.class)
|
||||
.wrapUp(root);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
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)
|
||||
* @see GHAppInstallation#createToken() GHAppInstallation#createToken()
|
||||
*/
|
||||
public class GHAppCreateTokenBuilder {
|
||||
private final GitHub root;
|
||||
protected final Requester builder;
|
||||
private final String apiUrlTail;
|
||||
|
||||
@Preview
|
||||
@Deprecated
|
||||
GHAppCreateTokenBuilder(GitHub root, String apiUrlTail) {
|
||||
this.root = root;
|
||||
this.apiUrlTail = apiUrlTail;
|
||||
this.builder = root.createRequest();
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Deprecated
|
||||
GHAppCreateTokenBuilder(GitHub root, String apiUrlTail, Map<String, GHPermissionType> permissions) {
|
||||
this(root, apiUrlTail);
|
||||
permissions(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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the permissions granted to the access token. The permissions object includes the permission names and their
|
||||
* access type.
|
||||
*
|
||||
* @param permissions
|
||||
* Map containing the permission names and types.
|
||||
* @return a GHAppCreateTokenBuilder
|
||||
*/
|
||||
@Preview
|
||||
@Deprecated
|
||||
public GHAppCreateTokenBuilder permissions(Map<String, GHPermissionType> permissions) {
|
||||
Map<String, String> retMap = new HashMap<>();
|
||||
for (Map.Entry<String, GHPermissionType> entry : permissions.entrySet()) {
|
||||
retMap.put(entry.getKey(), GitHubRequest.transformEnum(entry.getValue()));
|
||||
}
|
||||
builder.with("permissions", retMap);
|
||||
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)
|
||||
.withUrlPath(apiUrlTail)
|
||||
.fetch(GHAppInstallationToken.class)
|
||||
.wrapUp(root);
|
||||
}
|
||||
|
||||
}
|
||||
337
src/main/java/org/kohsuke/github/GHAppInstallation.java
Normal file
337
src/main/java/org/kohsuke/github/GHAppInstallation.java
Normal file
@@ -0,0 +1,337 @@
|
||||
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 GitHubClient.parseURL(htmlUrl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets root.
|
||||
*
|
||||
* @return the root
|
||||
*/
|
||||
public GitHub getRoot() {
|
||||
return root;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets root.
|
||||
*
|
||||
* @param root
|
||||
* the root
|
||||
* @deprecated Do not use this method. It was added due to incomplete understanding of Jackson binding.
|
||||
*/
|
||||
@Deprecated
|
||||
public void setRoot(GitHub root) {
|
||||
this.root = root;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets account.
|
||||
*
|
||||
* @return the account
|
||||
*/
|
||||
public GHUser getAccount() {
|
||||
return account;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets account.
|
||||
*
|
||||
* @param account
|
||||
* the account
|
||||
* @deprecated Do not use this method. It was added due to incomplete understanding of Jackson binding.
|
||||
*/
|
||||
@Deprecated
|
||||
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
|
||||
* @deprecated Do not use this method. It was added due to incomplete understanding of Jackson binding.
|
||||
*/
|
||||
@Deprecated
|
||||
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
|
||||
* @deprecated Do not use this method. It was added due to incomplete understanding of Jackson binding.
|
||||
*/
|
||||
@Deprecated
|
||||
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
|
||||
* @deprecated Do not use this method. It was added due to incomplete understanding of Jackson binding.
|
||||
*/
|
||||
@Deprecated
|
||||
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
|
||||
* @deprecated Do not use this method. It was added due to incomplete understanding of Jackson binding.
|
||||
*/
|
||||
@Deprecated
|
||||
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
|
||||
* @deprecated Do not use this method. It was added due to incomplete understanding of Jackson binding.
|
||||
*/
|
||||
@Deprecated
|
||||
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
|
||||
* @deprecated Do not use this method. It was added due to incomplete understanding of Jackson binding.
|
||||
*/
|
||||
@Deprecated
|
||||
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
|
||||
* @deprecated Do not use this method. It was added due to incomplete understanding of Jackson binding.
|
||||
*/
|
||||
@Deprecated
|
||||
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
|
||||
* @deprecated Do not use this method. It was added due to incomplete understanding of Jackson binding.
|
||||
*/
|
||||
@Deprecated
|
||||
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
|
||||
* @deprecated Do not use this method. It was added due to incomplete understanding of Jackson binding.
|
||||
*/
|
||||
@Deprecated
|
||||
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.createRequest()
|
||||
.method("DELETE")
|
||||
.withPreview(GAMBIT)
|
||||
.withUrlPath(String.format("/app/installations/%d", getId()))
|
||||
.send();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 instance
|
||||
* @deprecated Use {@link GHAppInstallation#createToken()} instead.
|
||||
*/
|
||||
@Preview
|
||||
@Deprecated
|
||||
public GHAppCreateTokenBuilder createToken(Map<String, GHPermissionType> permissions) {
|
||||
return new GHAppCreateTokenBuilder(root,
|
||||
String.format("/app/installations/%d/access_tokens", getId()),
|
||||
permissions);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @return a GHAppCreateTokenBuilder instance
|
||||
*/
|
||||
@Preview
|
||||
@Deprecated
|
||||
public GHAppCreateTokenBuilder createToken() {
|
||||
return new GHAppCreateTokenBuilder(root, String.format("/app/installations/%d/access_tokens", getId()));
|
||||
}
|
||||
}
|
||||
152
src/main/java/org/kohsuke/github/GHAppInstallationToken.java
Normal file
152
src/main/java/org/kohsuke/github/GHAppInstallationToken.java
Normal file
@@ -0,0 +1,152 @@
|
||||
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
|
||||
* @deprecated Do not use this method. It was added due to incomplete understanding of Jackson binding.
|
||||
*/
|
||||
@Deprecated
|
||||
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
|
||||
* @deprecated Do not use this method. It was added due to incomplete understanding of Jackson binding.
|
||||
*/
|
||||
@Deprecated
|
||||
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
|
||||
* @deprecated Do not use this method. It was added due to incomplete understanding of Jackson binding.
|
||||
*/
|
||||
@Deprecated
|
||||
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
|
||||
* @deprecated Do not use this method. It was added due to incomplete understanding of Jackson binding.
|
||||
*/
|
||||
@Deprecated
|
||||
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
|
||||
* @deprecated Do not use this method. It was added due to incomplete understanding of Jackson binding.
|
||||
*/
|
||||
@Deprecated
|
||||
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 GitHubClient.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;
|
||||
}
|
||||
}
|
||||
@@ -1,96 +1,155 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Date;
|
||||
import java.net.URL;
|
||||
|
||||
/**
|
||||
* Asset in a release.
|
||||
*
|
||||
* @see GHRelease#getAssets()
|
||||
* @see GHRelease#getAssets() GHRelease#getAssets()
|
||||
*/
|
||||
public class GHAsset {
|
||||
public class GHAsset extends GHObject {
|
||||
GitHub root;
|
||||
GHRepository owner;
|
||||
private String url;
|
||||
private String id;
|
||||
private String name;
|
||||
private String label;
|
||||
private String state;
|
||||
private String content_type;
|
||||
private long size;
|
||||
private long download_count;
|
||||
private Date created_at;
|
||||
private Date updated_at;
|
||||
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;
|
||||
}
|
||||
|
||||
public Date getCreatedAt() {
|
||||
return created_at;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets download count.
|
||||
*
|
||||
* @return the download count
|
||||
*/
|
||||
public long getDownloadCount() {
|
||||
return download_count;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
public Date getUpdatedAt() {
|
||||
return updated_at;
|
||||
/**
|
||||
* @deprecated This object has no HTML URL.
|
||||
*/
|
||||
@Override
|
||||
public URL getHtmlUrl() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
/**
|
||||
* 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());
|
||||
root.createRequest().with(key, value).method("PATCH").withUrlPath(getApiRoute()).send();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete.
|
||||
*
|
||||
* @throws IOException
|
||||
* the io exception
|
||||
*/
|
||||
public void delete() throws IOException {
|
||||
new Requester(root).method("DELETE").to(getApiRoute());
|
||||
root.createRequest().method("DELETE").withUrlPath(getApiRoute()).send();
|
||||
}
|
||||
|
||||
|
||||
private String getApiRoute() {
|
||||
return "/repos/" + owner.getOwnerName() + "/" + owner.getName() + "/releases/assets/" + id;
|
||||
return "/repos/" + owner.getOwnerName() + "/" + owner.getName() + "/releases/assets/" + getId();
|
||||
}
|
||||
|
||||
GHAsset wrap(GHRelease release) {
|
||||
@@ -99,6 +158,15 @@ public class GHAsset {
|
||||
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);
|
||||
|
||||
@@ -1,94 +1,170 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Generated OAuth token
|
||||
*
|
||||
* @author janinko
|
||||
* @see GitHub#createToken(Collection, String, String)
|
||||
* @see http://developer.github.com/v3/oauth/#create-a-new-authorization
|
||||
* @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 {
|
||||
public static final String USER = "user";
|
||||
public static final String USER_EMAIL = "user:email";
|
||||
public static final String USER_FOLLOW = "user:follow";
|
||||
public static final String PUBLIC_REPO = "public_repo";
|
||||
public static final String REPO = "repo";
|
||||
public static final String REPO_STATUS = "repo:status";
|
||||
public static final String DELETE_REPO = "delete_repo";
|
||||
public static final String NOTIFICATIONS = "notifications";
|
||||
public static final String GIST = "gist";
|
||||
public class GHAuthorization extends GHObject {
|
||||
public static final String USER = "user";
|
||||
public static final String USER_EMAIL = "user:email";
|
||||
public static final String USER_FOLLOW = "user:follow";
|
||||
public static final String PUBLIC_REPO = "public_repo";
|
||||
public static final String REPO = "repo";
|
||||
public static final String REPO_STATUS = "repo:status";
|
||||
public static final String DELETE_REPO = "delete_repo";
|
||||
public static final String NOTIFICATIONS = "notifications";
|
||||
public static final String GIST = "gist";
|
||||
public static final String READ_HOOK = "read:repo_hook";
|
||||
public static final String WRITE_HOOK = "write:repo_hook";
|
||||
public static final String AMIN_HOOK = "admin:repo_hook";
|
||||
public static final String READ_ORG = "read:org";
|
||||
public static final String WRITE_ORG = "write:org";
|
||||
public static final String ADMIN_ORG = "admin:org";
|
||||
public static final String READ_KEY = "read:public_key";
|
||||
public static final String WRITE_KEY = "write:public_key";
|
||||
public static final String ADMIN_KEY = "admin:public_key";
|
||||
|
||||
private GitHub root;
|
||||
private int id;
|
||||
private String url;
|
||||
private List<String> scopes;
|
||||
private String token;
|
||||
private App app;
|
||||
private String note;
|
||||
private String note_url;
|
||||
private String updated_at;
|
||||
private String created_at;
|
||||
private GitHub root;
|
||||
private List<String> scopes;
|
||||
private String token;
|
||||
private String token_last_eight;
|
||||
private String hashed_token;
|
||||
private App app;
|
||||
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;
|
||||
|
||||
/**
|
||||
* Gets root.
|
||||
*
|
||||
* @return the root
|
||||
*/
|
||||
public GitHub getRoot() {
|
||||
return root;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public List<String> getScopes() {
|
||||
return scopes;
|
||||
}
|
||||
|
||||
public String getToken(){
|
||||
return token;
|
||||
}
|
||||
|
||||
public URL getAppUrl(){
|
||||
return GitHub.parseURL(app.url);
|
||||
}
|
||||
|
||||
public String getAppName() {
|
||||
return app.name;
|
||||
}
|
||||
|
||||
public URL getApiURL(){
|
||||
return GitHub.parseURL(url);
|
||||
}
|
||||
|
||||
public String getNote() {
|
||||
return note;
|
||||
}
|
||||
|
||||
public URL getNoteUrl(){
|
||||
return GitHub.parseURL(note_url);
|
||||
}
|
||||
|
||||
public Date getCreatedAt() {
|
||||
return GitHub.parseDate(created_at);
|
||||
/**
|
||||
* Gets scopes.
|
||||
*
|
||||
* @return the scopes
|
||||
*/
|
||||
public List<String> getScopes() {
|
||||
return scopes;
|
||||
}
|
||||
|
||||
public Date getUpdatedAt() {
|
||||
return GitHub.parseDate(updated_at);
|
||||
/**
|
||||
* Gets token.
|
||||
*
|
||||
* @return the token
|
||||
*/
|
||||
public String getToken() {
|
||||
return token;
|
||||
}
|
||||
|
||||
/*package*/ GHAuthorization wrap(GitHub root) {
|
||||
this.root = root;
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* 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 GitHubClient.parseURL(app.url);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets app name.
|
||||
*
|
||||
* @return the app name
|
||||
*/
|
||||
public String getAppName() {
|
||||
return app.name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets api url.
|
||||
*
|
||||
* @return the api url
|
||||
* @deprecated use {@link #getUrl()}
|
||||
*/
|
||||
@Deprecated
|
||||
@SuppressFBWarnings(value = "NM_CONFUSING", justification = "It's a part of the library API, cannot be changed")
|
||||
public URL getApiURL() {
|
||||
return getUrl();
|
||||
}
|
||||
|
||||
private static class App{
|
||||
private String url;
|
||||
private String name;
|
||||
}
|
||||
/**
|
||||
* @deprecated This object has no HTML URL.
|
||||
*/
|
||||
@Override
|
||||
public URL getHtmlUrl() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets note.
|
||||
*
|
||||
* @return the note
|
||||
*/
|
||||
public String getNote() {
|
||||
return note;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets note url.
|
||||
*
|
||||
* @return the note url
|
||||
*/
|
||||
public URL getNoteUrl() {
|
||||
return GitHubClient.parseURL(note_url);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets fingerprint.
|
||||
*
|
||||
* @return the fingerprint
|
||||
*/
|
||||
public String getFingerprint() {
|
||||
return fingerprint;
|
||||
}
|
||||
|
||||
GHAuthorization wrap(GitHub root) {
|
||||
this.root = root;
|
||||
return this;
|
||||
}
|
||||
|
||||
@SuppressFBWarnings(value = { "UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD" },
|
||||
justification = "JSON API")
|
||||
private static class App {
|
||||
private String url;
|
||||
private String name;
|
||||
// private String client_id; not yet used
|
||||
}
|
||||
}
|
||||
|
||||
83
src/main/java/org/kohsuke/github/GHBlob.java
Normal file
83
src/main/java/org/kohsuke/github/GHBlob.java
Normal file
@@ -0,0 +1,83 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.util.Base64;
|
||||
|
||||
/**
|
||||
* The type GHBlob.
|
||||
*
|
||||
* @author Kanstantsin Shautsou
|
||||
* @author Kohsuke Kawaguchi
|
||||
* @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 {
|
||||
private String content, encoding, url, sha;
|
||||
private long size;
|
||||
|
||||
/**
|
||||
* Gets url.
|
||||
*
|
||||
* @return API URL of this blob.
|
||||
*/
|
||||
public URL getUrl() {
|
||||
return GitHubClient.parseURL(url);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets sha.
|
||||
*
|
||||
* @return the sha
|
||||
*/
|
||||
public String getSha() {
|
||||
return sha;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets size.
|
||||
*
|
||||
* @return Number of bytes in this blob.
|
||||
*/
|
||||
public long getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets encoding.
|
||||
*
|
||||
* @return the encoding
|
||||
*/
|
||||
public String getEncoding() {
|
||||
return encoding;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets content.
|
||||
*
|
||||
* @return Encoded content. You probably want {@link #read()}
|
||||
*/
|
||||
public String getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read input stream.
|
||||
*
|
||||
* @return the actual bytes of the blob.
|
||||
*/
|
||||
public InputStream read() {
|
||||
if (encoding.equals("base64")) {
|
||||
try {
|
||||
Base64.Decoder decoder = Base64.getMimeDecoder();
|
||||
return new ByteArrayInputStream(decoder.decode(content));
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new AssertionError(e); // US-ASCII is mandatory
|
||||
}
|
||||
}
|
||||
|
||||
throw new UnsupportedOperationException("Unrecognized encoding: " + encoding);
|
||||
}
|
||||
}
|
||||
59
src/main/java/org/kohsuke/github/GHBlobBuilder.java
Normal file
59
src/main/java/org/kohsuke/github/GHBlobBuilder.java
Normal file
@@ -0,0 +1,59 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Base64;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
private final Requester req;
|
||||
|
||||
GHBlobBuilder(GHRepository repo) {
|
||||
this.repo = repo;
|
||||
req = repo.root.createRequest();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
req.with("encoding", "utf-8");
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.getEncoder().encodeToString(content);
|
||||
req.with("content", base64Content);
|
||||
req.with("encoding", "base64");
|
||||
return this;
|
||||
}
|
||||
|
||||
private String getApiTail() {
|
||||
return String.format("/repos/%s/%s/git/blobs", repo.getOwnerName(), repo.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* 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").withUrlPath(getApiTail()).fetch(GHBlob.class);
|
||||
}
|
||||
}
|
||||
@@ -1,49 +1,177 @@
|
||||
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;
|
||||
|
||||
/**
|
||||
* A branch in a repository.
|
||||
*
|
||||
*
|
||||
* @author Yusuke Kokubo
|
||||
*/
|
||||
@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;
|
||||
|
||||
private String name;
|
||||
private Commit commit;
|
||||
@JsonProperty("protected")
|
||||
private boolean protection;
|
||||
private String protection_url;
|
||||
|
||||
public static class Commit {
|
||||
String sha,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;
|
||||
|
||||
@SuppressFBWarnings(value = "UUF_UNUSED_FIELD", justification = "We don't provide it in API now")
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* The commit that this branch currently points to.
|
||||
* Is protected boolean.
|
||||
*
|
||||
* @return true if the push to this branch is restricted via branch protection.
|
||||
*/
|
||||
@Preview
|
||||
@Deprecated
|
||||
public boolean isProtected() {
|
||||
return protection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets protection url.
|
||||
*
|
||||
* @return API URL that deals with the protection of this branch.
|
||||
*/
|
||||
@Preview
|
||||
@Deprecated
|
||||
public URL getProtectionUrl() {
|
||||
return GitHubClient.parseURL(protection_url);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets protection.
|
||||
*
|
||||
* @return the protection
|
||||
* @throws IOException
|
||||
* the io exception
|
||||
*/
|
||||
public GHBranchProtection getProtection() throws IOException {
|
||||
return root.createRequest().setRawUrlPath(protection_url).fetch(GHBranchProtection.class).wrap(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets sha 1.
|
||||
*
|
||||
* @return The SHA1 of the commit that this branch currently points to.
|
||||
*/
|
||||
public String getSHA1() {
|
||||
return commit.sha;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Branch:" + name + " in " + owner.getUrl();
|
||||
/**
|
||||
* Disables branch protection and allows anyone with push access to push changes.
|
||||
*
|
||||
* @throws IOException
|
||||
* if disabling protection fails
|
||||
*/
|
||||
public void disableProtection() throws IOException {
|
||||
root.createRequest().method("DELETE").setRawUrlPath(protection_url).send();
|
||||
}
|
||||
|
||||
/*package*/ GHBranch wrap(GHRepository repo) {
|
||||
/**
|
||||
* Enables branch protection to control what commit statuses are required to push.
|
||||
*
|
||||
* @return GHBranchProtectionBuilder for enabling protection
|
||||
* @see GHCommitStatus#getContext() GHCommitStatus#getContext()
|
||||
*/
|
||||
@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;
|
||||
}
|
||||
}
|
||||
|
||||
String getApiRoute() {
|
||||
return owner.getApiTailUrl("/branches/" + name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final String url = owner != null ? owner.getUrl().toString() : "unknown";
|
||||
return "Branch:" + name + " in " + url;
|
||||
}
|
||||
|
||||
GHBranch wrap(GHRepository repo) {
|
||||
this.owner = repo;
|
||||
this.root = repo.root;
|
||||
return this;
|
||||
|
||||
350
src/main/java/org/kohsuke/github/GHBranchProtection.java
Normal file
350
src/main/java/org/kohsuke/github/GHBranchProtection.java
Normal file
@@ -0,0 +1,350 @@
|
||||
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;
|
||||
|
||||
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 {
|
||||
private static final String REQUIRE_SIGNATURES_URI = "/required_signatures";
|
||||
|
||||
@JsonProperty
|
||||
private EnforceAdmins enforceAdmins;
|
||||
|
||||
private GitHub root;
|
||||
|
||||
@JsonProperty("required_pull_request_reviews")
|
||||
private RequiredReviews requiredReviews;
|
||||
|
||||
@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").withUrlPath(url + REQUIRE_SIGNATURES_URI).fetch(RequiredSignatures.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable signed commits.
|
||||
*
|
||||
* @throws IOException
|
||||
* the io exception
|
||||
*/
|
||||
@Preview
|
||||
@Deprecated
|
||||
public void disableSignedCommits() throws IOException {
|
||||
requester().method("DELETE").withUrlPath(url + REQUIRE_SIGNATURES_URI).send();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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().withUrlPath(url + REQUIRE_SIGNATURES_URI).fetch(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 root.createRequest().withPreview(ZZZAX);
|
||||
}
|
||||
|
||||
/**
|
||||
* The type EnforceAdmins.
|
||||
*/
|
||||
public static class EnforceAdmins {
|
||||
@JsonProperty
|
||||
private boolean enabled;
|
||||
|
||||
@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 RequiredReviews.
|
||||
*/
|
||||
public static class RequiredReviews {
|
||||
@JsonProperty("dismissal_restrictions")
|
||||
private Restrictions dismissalRestriction;
|
||||
|
||||
private boolean dismissStaleReviews;
|
||||
|
||||
private boolean requireCodeOwnerReviews;
|
||||
|
||||
@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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets required reviewers.
|
||||
*
|
||||
* @return the required reviewers
|
||||
*/
|
||||
public int getRequiredReviewers() {
|
||||
return requiredReviewers;
|
||||
}
|
||||
}
|
||||
|
||||
private static class RequiredSignatures {
|
||||
@JsonProperty
|
||||
private boolean enabled;
|
||||
|
||||
@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;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The type Restrictions.
|
||||
*/
|
||||
public static class Restrictions {
|
||||
@JsonProperty
|
||||
private Collection<GHTeam> teams;
|
||||
|
||||
private String teamsUrl;
|
||||
|
||||
@JsonProperty
|
||||
private String url;
|
||||
|
||||
@JsonProperty
|
||||
private Collection<GHUser> users;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
368
src/main/java/org/kohsuke/github/GHBranchProtectionBuilder.java
Normal file
368
src/main/java/org/kohsuke/github/GHBranchProtectionBuilder.java
Normal file
@@ -0,0 +1,368 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.kohsuke.github.Previews.*;
|
||||
|
||||
/**
|
||||
* Builder to configure the branch protection settings.
|
||||
*
|
||||
* @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")
|
||||
public class GHBranchProtectionBuilder {
|
||||
private final GHBranch branch;
|
||||
|
||||
private boolean enforceAdmins;
|
||||
private Map<String, Object> prReviews;
|
||||
private Restrictions restrictions;
|
||||
private StatusChecks statusChecks;
|
||||
|
||||
GHBranchProtectionBuilder(GHBranch branch) {
|
||||
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() {
|
||||
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)
|
||||
.withUrlPath(branch.getProtectionUrl().toString())
|
||||
.fetch(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);
|
||||
}
|
||||
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());
|
||||
}
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
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());
|
||||
}
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
private void addReviewRestriction(String restriction, boolean isTeam) {
|
||||
restrictReviewDismissals();
|
||||
Restrictions restrictions = (Restrictions) prReviews.get("dismissal_restrictions");
|
||||
|
||||
if (isTeam) {
|
||||
restrictions.teams.add(restriction);
|
||||
} else {
|
||||
restrictions.users.add(restriction);
|
||||
}
|
||||
}
|
||||
|
||||
private Map<String, Object> getPrReviews() {
|
||||
if (prReviews == null) {
|
||||
prReviews = new HashMap<String, Object>();
|
||||
}
|
||||
return prReviews;
|
||||
}
|
||||
|
||||
private Restrictions getRestrictions() {
|
||||
if (restrictions == null) {
|
||||
restrictions = new Restrictions();
|
||||
}
|
||||
return restrictions;
|
||||
}
|
||||
|
||||
private StatusChecks getStatusChecks() {
|
||||
if (statusChecks == null) {
|
||||
statusChecks = new StatusChecks();
|
||||
}
|
||||
return statusChecks;
|
||||
}
|
||||
|
||||
private Requester requester() {
|
||||
return branch.getRoot().createRequest().withPreview(LUKE_CAGE);
|
||||
}
|
||||
|
||||
private static class Restrictions {
|
||||
private Set<String> teams = new HashSet<String>();
|
||||
private Set<String> users = new HashSet<String>();
|
||||
}
|
||||
|
||||
private static class StatusChecks {
|
||||
final List<String> contexts = new ArrayList<String>();
|
||||
boolean strict;
|
||||
}
|
||||
}
|
||||
259
src/main/java/org/kohsuke/github/GHCheckRun.java
Normal file
259
src/main/java/org/kohsuke/github/GHCheckRun.java
Normal file
@@ -0,0 +1,259 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* Represents a check run.
|
||||
*
|
||||
* @see <a href="https://developer.github.com/v3/checks/runs/">documentation</a>
|
||||
*/
|
||||
@SuppressFBWarnings(value = { "UWF_UNWRITTEN_FIELD", "NP_UNWRITTEN_FIELD", "URF_UNREAD_FIELD" },
|
||||
justification = "JSON API")
|
||||
public class GHCheckRun extends GHObject {
|
||||
GHRepository owner;
|
||||
GitHub root;
|
||||
|
||||
private String status;
|
||||
private String conclusion;
|
||||
private String name;
|
||||
private String headSha;
|
||||
private String nodeId;
|
||||
private String externalId;
|
||||
private String startedAt;
|
||||
private String completedAt;
|
||||
private URL htmlUrl;
|
||||
private URL detailsUrl;
|
||||
private Output output;
|
||||
private GHApp app;
|
||||
private GHPullRequest[] pullRequests;
|
||||
private GHCheckSuite checkSuite;
|
||||
|
||||
GHCheckRun wrap(GHRepository owner) {
|
||||
this.owner = owner;
|
||||
this.root = owner.root;
|
||||
return this;
|
||||
}
|
||||
|
||||
GHCheckRun wrap(GitHub root) {
|
||||
this.root = root;
|
||||
if (owner != null) {
|
||||
owner.wrap(root);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
GHPullRequest[] wrap() {
|
||||
return pullRequests;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets status of the check run.
|
||||
*
|
||||
* @return Status of the check run
|
||||
* @see Status
|
||||
*/
|
||||
public String getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public static enum Status {
|
||||
QUEUED, IN_PROGRESS, COMPLETED
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets conclusion of a completed check run.
|
||||
*
|
||||
* @return Status of the check run
|
||||
* @see Conclusion
|
||||
*/
|
||||
public String getConclusion() {
|
||||
return conclusion;
|
||||
}
|
||||
|
||||
public static enum Conclusion {
|
||||
SUCCESS, FAILURE, NEUTRAL, CANCELLED, TIMED_OUT, ACTION_REQUIRED
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the custom name of this check run.
|
||||
*
|
||||
* @return Name of the check run
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the HEAD SHA.
|
||||
*
|
||||
* @return sha for the HEAD commit
|
||||
*/
|
||||
public String getHeadSha() {
|
||||
return headSha;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the pull requests participated in this check run.
|
||||
*
|
||||
* @return Pull requests of this check run
|
||||
*/
|
||||
GHPullRequest[] getPullRequests() throws IOException {
|
||||
if (pullRequests != null && pullRequests.length != 0) {
|
||||
for (GHPullRequest singlePull : pullRequests) {
|
||||
singlePull.refresh();
|
||||
}
|
||||
}
|
||||
return pullRequests;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the HTML URL: https://github.com/[owner]/[repo-name]/runs/[check-run-id], usually an GitHub Action page of
|
||||
* the check run.
|
||||
*
|
||||
* @return HTML URL
|
||||
*/
|
||||
@Override
|
||||
public URL getHtmlUrl() {
|
||||
return htmlUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the global node id to access most objects in GitHub.
|
||||
*
|
||||
* @see <a href="https://developer.github.com/v4/guides/using-global-node-ids/">documentation</a>
|
||||
* @return Global node id
|
||||
*/
|
||||
public String getNodeId() {
|
||||
return nodeId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a reference for the check run on the integrator's system.
|
||||
*
|
||||
* @return Reference id
|
||||
*/
|
||||
public String getExternalId() {
|
||||
return externalId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the details URL from which to find full details of the check run on the integrator's site.
|
||||
*
|
||||
* @return Details URL
|
||||
*/
|
||||
public URL getDetailsUrl() {
|
||||
return detailsUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the start time of the check run in ISO 8601 format: YYYY-MM-DDTHH:MM:SSZ.
|
||||
*
|
||||
* @return Timestamp of the start time
|
||||
*/
|
||||
public Date getStartedAt() {
|
||||
return GitHubClient.parseDate(startedAt);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the completed time of the check run in ISO 8601 format: YYYY-MM-DDTHH:MM:SSZ.
|
||||
*
|
||||
* @return Timestamp of the completed time
|
||||
*/
|
||||
public Date getCompletedAt() {
|
||||
return GitHubClient.parseDate(completedAt);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the GitHub app this check run belongs to, included in response.
|
||||
*
|
||||
* @return GitHub App
|
||||
*/
|
||||
public GHApp getApp() {
|
||||
return app;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the check suite this check run belongs to
|
||||
*
|
||||
* @return Check suite
|
||||
*/
|
||||
public GHCheckSuite getCheckSuite() {
|
||||
return checkSuite;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an output for a check run.
|
||||
*
|
||||
* @return Output of a check run
|
||||
*/
|
||||
public Output getOutput() {
|
||||
return output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents an output in a check run to include summary and other results.
|
||||
*
|
||||
* @see <a href="https://developer.github.com/v3/checks/runs/#output-object">documentation</a>
|
||||
*/
|
||||
public static class Output {
|
||||
private String title;
|
||||
private String summary;
|
||||
private String text;
|
||||
private int annotationsCount;
|
||||
private URL annotationsUrl;
|
||||
|
||||
/**
|
||||
* Gets the title of check run.
|
||||
*
|
||||
* @return title of check run
|
||||
*/
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the summary of the check run, note that it supports Markdown.
|
||||
*
|
||||
* @return summary of check run
|
||||
*/
|
||||
public String getSummary() {
|
||||
return summary;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the details of the check run, note that it supports Markdown.
|
||||
*
|
||||
* @return Details of the check run
|
||||
*/
|
||||
public String getText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the annotation count of a check run.
|
||||
*
|
||||
* @return annotation count of a check run
|
||||
*/
|
||||
public int getAnnotationsCount() {
|
||||
return annotationsCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the URL of annotations.
|
||||
*
|
||||
* @return URL of annotations
|
||||
*/
|
||||
public URL getAnnotationsUrl() {
|
||||
return annotationsUrl;
|
||||
}
|
||||
}
|
||||
|
||||
public static enum AnnotationLevel {
|
||||
NOTICE, WARNING, FAILURE
|
||||
}
|
||||
|
||||
}
|
||||
291
src/main/java/org/kohsuke/github/GHCheckRunBuilder.java
Normal file
291
src/main/java/org/kohsuke/github/GHCheckRunBuilder.java
Normal file
@@ -0,0 +1,291 @@
|
||||
/*
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright 2020 CloudBees, Inc.
|
||||
*
|
||||
* 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 com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import edu.umd.cs.findbugs.annotations.CheckForNull;
|
||||
import edu.umd.cs.findbugs.annotations.NonNull;
|
||||
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* Drafts a check run.
|
||||
*
|
||||
* @see GHCheckRun
|
||||
* @see GHRepository#createCheckRun
|
||||
* @see <a href="https://developer.github.com/v3/checks/runs/#create-a-check-run">documentation</a>
|
||||
*/
|
||||
@SuppressFBWarnings(value = "URF_UNREAD_FIELD", justification = "Jackson serializes these even without a getter")
|
||||
@Preview
|
||||
@Deprecated
|
||||
public final class GHCheckRunBuilder {
|
||||
|
||||
private final GHRepository repo;
|
||||
private final Requester requester;
|
||||
private Output output;
|
||||
private List<Action> actions;
|
||||
|
||||
GHCheckRunBuilder(GHRepository repo, String name, String headSHA) {
|
||||
this.repo = repo;
|
||||
requester = repo.root.createRequest()
|
||||
.withPreview(Previews.ANTIOPE)
|
||||
.method("POST")
|
||||
.with("name", name)
|
||||
.with("head_sha", headSHA)
|
||||
.withUrlPath(repo.getApiTailUrl("check-runs"));
|
||||
}
|
||||
|
||||
public @NonNull GHCheckRunBuilder withDetailsURL(@CheckForNull String detailsURL) {
|
||||
requester.with("details_url", detailsURL);
|
||||
return this;
|
||||
}
|
||||
|
||||
public @NonNull GHCheckRunBuilder withExternalID(@CheckForNull String externalID) {
|
||||
requester.with("external_id", externalID);
|
||||
return this;
|
||||
}
|
||||
|
||||
public @NonNull GHCheckRunBuilder withStatus(@CheckForNull GHCheckRun.Status status) {
|
||||
if (status != null) {
|
||||
// Do *not* use the overload taking Enum, as that s/_/-/g which would be wrong here.
|
||||
requester.with("status", status.toString().toLowerCase(Locale.ROOT));
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public @NonNull GHCheckRunBuilder withConclusion(@CheckForNull GHCheckRun.Conclusion conclusion) {
|
||||
if (conclusion != null) {
|
||||
requester.with("conclusion", conclusion.toString().toLowerCase(Locale.ROOT));
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public @NonNull GHCheckRunBuilder withStartedAt(@CheckForNull Date startedAt) {
|
||||
if (startedAt != null) {
|
||||
requester.with("started_at", GitHubClient.printDate(startedAt));
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public @NonNull GHCheckRunBuilder withCompletedAt(@CheckForNull Date completedAt) {
|
||||
if (completedAt != null) {
|
||||
requester.with("completed_at", GitHubClient.printDate(completedAt));
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public @NonNull GHCheckRunBuilder add(@NonNull Output output) {
|
||||
if (this.output != null) {
|
||||
throw new IllegalStateException("cannot add Output twice");
|
||||
}
|
||||
this.output = output;
|
||||
return this;
|
||||
}
|
||||
|
||||
public @NonNull GHCheckRunBuilder add(@NonNull Action action) {
|
||||
if (actions == null) {
|
||||
actions = new LinkedList<>();
|
||||
}
|
||||
actions.add(action);
|
||||
return this;
|
||||
}
|
||||
|
||||
private static final int MAX_ANNOTATIONS = 50;
|
||||
/**
|
||||
* Actually creates the check run. (If more than fifty annotations were requested, this is done in batches.)
|
||||
*
|
||||
* @return the resulting run
|
||||
* @throws IOException
|
||||
* for the usual reasons
|
||||
*/
|
||||
public @NonNull GHCheckRun create() throws IOException {
|
||||
List<Annotation> extraAnnotations;
|
||||
if (output != null && output.annotations != null && output.annotations.size() > MAX_ANNOTATIONS) {
|
||||
extraAnnotations = output.annotations.subList(MAX_ANNOTATIONS, output.annotations.size());
|
||||
output.annotations = output.annotations.subList(0, MAX_ANNOTATIONS);
|
||||
} else {
|
||||
extraAnnotations = Collections.emptyList();
|
||||
}
|
||||
GHCheckRun run = requester.with("output", output).with("actions", actions).fetch(GHCheckRun.class).wrap(repo);
|
||||
while (!extraAnnotations.isEmpty()) {
|
||||
Output output2 = new Output(output.title, output.summary);
|
||||
int i = Math.min(extraAnnotations.size(), MAX_ANNOTATIONS);
|
||||
output2.annotations = extraAnnotations.subList(0, i);
|
||||
extraAnnotations = extraAnnotations.subList(i, extraAnnotations.size());
|
||||
run = repo.root.createRequest()
|
||||
.withPreview(Previews.ANTIOPE)
|
||||
.method("PATCH")
|
||||
.with("output", output2)
|
||||
.withUrlPath(repo.getApiTailUrl("check-runs/" + run.getId()))
|
||||
.fetch(GHCheckRun.class)
|
||||
.wrap(repo);
|
||||
}
|
||||
return run;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see <a href="https://developer.github.com/v3/checks/runs/#output-object">documentation</a>
|
||||
*/
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
public static final class Output {
|
||||
|
||||
private final String title;
|
||||
private final String summary;
|
||||
private String text;
|
||||
private List<Annotation> annotations;
|
||||
private List<Image> images;
|
||||
|
||||
public Output(@NonNull String title, @NonNull String summary) {
|
||||
this.title = title;
|
||||
this.summary = summary;
|
||||
}
|
||||
|
||||
public @NonNull Output withText(@CheckForNull String text) {
|
||||
this.text = text;
|
||||
return this;
|
||||
}
|
||||
|
||||
public @NonNull Output add(@NonNull Annotation annotation) {
|
||||
if (annotations == null) {
|
||||
annotations = new LinkedList<>();
|
||||
}
|
||||
annotations.add(annotation);
|
||||
return this;
|
||||
}
|
||||
|
||||
public @NonNull Output add(@NonNull Image image) {
|
||||
if (images == null) {
|
||||
images = new LinkedList<>();
|
||||
}
|
||||
images.add(image);
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @see <a href="https://developer.github.com/v3/checks/runs/#annotations-object">documentation</a>
|
||||
*/
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
public static final class Annotation {
|
||||
|
||||
private final String path;
|
||||
private final int start_line;
|
||||
private final int end_line;
|
||||
private final String annotation_level;
|
||||
private final String message;
|
||||
private Integer start_column;
|
||||
private Integer end_column;
|
||||
private String title;
|
||||
private String raw_details;
|
||||
|
||||
public Annotation(@NonNull String path,
|
||||
int line,
|
||||
@NonNull GHCheckRun.AnnotationLevel annotationLevel,
|
||||
@NonNull String message) {
|
||||
this(path, line, line, annotationLevel, message);
|
||||
}
|
||||
|
||||
public Annotation(@NonNull String path,
|
||||
int startLine,
|
||||
int endLine,
|
||||
@NonNull GHCheckRun.AnnotationLevel annotationLevel,
|
||||
@NonNull String message) {
|
||||
this.path = path;
|
||||
start_line = startLine;
|
||||
end_line = endLine;
|
||||
annotation_level = annotationLevel.toString().toLowerCase(Locale.ROOT);
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public @NonNull Annotation withStartColumn(@CheckForNull Integer startColumn) {
|
||||
start_column = startColumn;
|
||||
return this;
|
||||
}
|
||||
|
||||
public @NonNull Annotation withEndColumn(@CheckForNull Integer endColumn) {
|
||||
end_column = endColumn;
|
||||
return this;
|
||||
}
|
||||
|
||||
public @NonNull Annotation withTitle(@CheckForNull String title) {
|
||||
this.title = title;
|
||||
return this;
|
||||
}
|
||||
|
||||
public @NonNull Annotation withRawDetails(@CheckForNull String rawDetails) {
|
||||
raw_details = rawDetails;
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @see <a href="https://developer.github.com/v3/checks/runs/#images-object">documentation</a>
|
||||
*/
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
public static final class Image {
|
||||
|
||||
private final String alt;
|
||||
private final String image_url;
|
||||
private String caption;
|
||||
|
||||
public Image(@NonNull String alt, @NonNull String imageURL) {
|
||||
this.alt = alt;
|
||||
image_url = imageURL;
|
||||
}
|
||||
|
||||
public @NonNull Image withCaption(@CheckForNull String caption) {
|
||||
this.caption = caption;
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @see <a href="https://developer.github.com/v3/checks/runs/#actions-object">documentation</a>
|
||||
*/
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
public static final class Action {
|
||||
|
||||
private final String label;
|
||||
private final String description;
|
||||
private final String identifier;
|
||||
|
||||
public Action(@NonNull String label, @NonNull String description, @NonNull String identifier) {
|
||||
this.label = label;
|
||||
this.description = description;
|
||||
this.identifier = identifier;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
44
src/main/java/org/kohsuke/github/GHCheckRunsIterable.java
Normal file
44
src/main/java/org/kohsuke/github/GHCheckRunsIterable.java
Normal file
@@ -0,0 +1,44 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
/**
|
||||
* Iterable for check-runs listing.
|
||||
*/
|
||||
class GHCheckRunsIterable extends PagedIterable<GHCheckRun> {
|
||||
private GitHub root;
|
||||
private final GitHubRequest request;
|
||||
|
||||
private GHCheckRunsPage result;
|
||||
|
||||
public GHCheckRunsIterable(GitHub root, GitHubRequest request) {
|
||||
this.root = root;
|
||||
this.request = request;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public PagedIterator<GHCheckRun> _iterator(int pageSize) {
|
||||
return new PagedIterator<>(
|
||||
adapt(GitHubPageIterator.create(root.getClient(), GHCheckRunsPage.class, request, pageSize)),
|
||||
null);
|
||||
}
|
||||
|
||||
protected Iterator<GHCheckRun[]> adapt(final Iterator<GHCheckRunsPage> base) {
|
||||
return new Iterator<GHCheckRun[]>() {
|
||||
public boolean hasNext() {
|
||||
return base.hasNext();
|
||||
}
|
||||
|
||||
public GHCheckRun[] next() {
|
||||
GHCheckRunsPage v = base.next();
|
||||
if (result == null) {
|
||||
result = v;
|
||||
}
|
||||
return v.getCheckRuns(root);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
20
src/main/java/org/kohsuke/github/GHCheckRunsPage.java
Normal file
20
src/main/java/org/kohsuke/github/GHCheckRunsPage.java
Normal file
@@ -0,0 +1,20 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
/**
|
||||
* Represents the one page of check-runs result when listing check-runs.
|
||||
*/
|
||||
class GHCheckRunsPage {
|
||||
private int total_count;
|
||||
private GHCheckRun[] check_runs;
|
||||
|
||||
public int getTotalCount() {
|
||||
return total_count;
|
||||
}
|
||||
|
||||
GHCheckRun[] getCheckRuns(GitHub root) {
|
||||
for (GHCheckRun check_run : check_runs) {
|
||||
check_run.wrap(root);
|
||||
}
|
||||
return check_runs;
|
||||
}
|
||||
}
|
||||
239
src/main/java/org/kohsuke/github/GHCheckSuite.java
Normal file
239
src/main/java/org/kohsuke/github/GHCheckSuite.java
Normal file
@@ -0,0 +1,239 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* Represents a check suite.
|
||||
*
|
||||
* @see <a href="https://developer.github.com/v3/checks/suites/">documentation</a>
|
||||
*/
|
||||
@SuppressFBWarnings(value = { "UWF_UNWRITTEN_FIELD", "NP_UNWRITTEN_FIELD", "URF_UNREAD_FIELD" },
|
||||
justification = "JSON API")
|
||||
public class GHCheckSuite extends GHObject {
|
||||
GHRepository owner;
|
||||
GitHub root;
|
||||
|
||||
private String nodeId;
|
||||
private String headBranch;
|
||||
private String headSha;
|
||||
private String status;
|
||||
private String conclusion;
|
||||
private String before;
|
||||
private String after;
|
||||
private int latestCheckRunsCount;
|
||||
private URL checkRunsUrl;
|
||||
private HeadCommit headCommit;
|
||||
private GHApp app;
|
||||
private GHPullRequest[] pullRequests;
|
||||
|
||||
GHCheckSuite wrap(GHRepository owner) {
|
||||
this.owner = owner;
|
||||
this.root = owner.root;
|
||||
return this;
|
||||
}
|
||||
|
||||
GHCheckSuite wrap(GitHub root) {
|
||||
this.root = root;
|
||||
if (owner != null) {
|
||||
owner.wrap(root);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
GHPullRequest[] wrap() {
|
||||
return pullRequests;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the global node id to access most objects in GitHub.
|
||||
*
|
||||
* @see <a href="https://developer.github.com/v4/guides/using-global-node-ids/">documentation</a>
|
||||
* @return global node id
|
||||
*/
|
||||
public String getNodeId() {
|
||||
return nodeId;
|
||||
}
|
||||
|
||||
/**
|
||||
* The head branch name the changes are on.
|
||||
*
|
||||
* @return head branch name
|
||||
*/
|
||||
public String getHeadBranch() {
|
||||
return headBranch;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the HEAD SHA.
|
||||
*
|
||||
* @return sha for the HEAD commit
|
||||
*/
|
||||
public String getHeadSha() {
|
||||
return headSha;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets status of the check suite. It can be one of request, in_progress, or completed.
|
||||
*
|
||||
* @return status of the check suite
|
||||
*/
|
||||
public String getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets conclusion of a completed check suite. It can be one of success, failure, neutral, cancelled, time_out,
|
||||
* action_required, or stale. The check suite will report the highest priority check run conclusion in the check
|
||||
* suite's conclusion.
|
||||
*
|
||||
* @return conclusion of the check suite
|
||||
*/
|
||||
public String getConclusion() {
|
||||
return conclusion;
|
||||
}
|
||||
|
||||
/**
|
||||
* The SHA of the most recent commit on ref before the push.
|
||||
*
|
||||
* @return sha of a commit
|
||||
*/
|
||||
public String getBefore() {
|
||||
return before;
|
||||
}
|
||||
|
||||
/**
|
||||
* The SHA of the most recent commit on ref after the push.
|
||||
*
|
||||
* @return sha of a commit
|
||||
*/
|
||||
public String getAfter() {
|
||||
return after;
|
||||
}
|
||||
|
||||
/**
|
||||
* The quantity of check runs that had run as part of the latest push.
|
||||
*
|
||||
* @return sha of the most recent commit
|
||||
*/
|
||||
public int getLatestCheckRunsCount() {
|
||||
return latestCheckRunsCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* The url used to list all the check runs belonged to this suite.
|
||||
*
|
||||
* @return url containing all check runs
|
||||
*/
|
||||
public URL getCheckRunsUrl() {
|
||||
return checkRunsUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* The commit of current head.
|
||||
*
|
||||
* @return head commit
|
||||
*/
|
||||
public HeadCommit getHeadCommit() {
|
||||
return headCommit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the GitHub app this check suite belongs to, included in response.
|
||||
*
|
||||
* @return GitHub App
|
||||
*/
|
||||
public GHApp getApp() {
|
||||
return app;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the pull requests participated in this check suite.
|
||||
*
|
||||
* @return Pull requests
|
||||
*/
|
||||
GHPullRequest[] getPullRequests() throws IOException {
|
||||
if (pullRequests != null && pullRequests.length != 0) {
|
||||
for (GHPullRequest singlePull : pullRequests) {
|
||||
singlePull.refresh();
|
||||
}
|
||||
}
|
||||
return pullRequests;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check suite doesn't have a HTML URL.
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
@Override
|
||||
public URL getHtmlUrl() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static class HeadCommit {
|
||||
private String id;
|
||||
private String treeId;
|
||||
private String message;
|
||||
private String timestamp;
|
||||
private GitUser author;
|
||||
private GitUser committer;
|
||||
|
||||
/**
|
||||
* Gets id of the commit, used by {@link GHCheckSuite} when a {@link GHEvent#CHECK_SUITE} comes
|
||||
*
|
||||
* @return id of the commit
|
||||
*/
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets id of the tree.
|
||||
*
|
||||
* @return id of the tree
|
||||
*/
|
||||
public String getTreeId() {
|
||||
return treeId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets message.
|
||||
*
|
||||
* @return commit message.
|
||||
*/
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets timestamp of the commit.
|
||||
*
|
||||
* @return timestamp of the commit
|
||||
*/
|
||||
public Date getTimestamp() {
|
||||
return GitHubClient.parseDate(timestamp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets author.
|
||||
*
|
||||
* @return the author
|
||||
*/
|
||||
public GitUser getAuthor() {
|
||||
return author;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets committer.
|
||||
*
|
||||
* @return the committer
|
||||
*/
|
||||
public GitUser getCommitter() {
|
||||
return committer;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -1,5 +1,8 @@
|
||||
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.net.URL;
|
||||
import java.util.AbstractList;
|
||||
@@ -12,191 +15,335 @@ 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")
|
||||
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")
|
||||
public static class ShortInfo {
|
||||
private GHAuthor author;
|
||||
private GHAuthor committer;
|
||||
|
||||
|
||||
private String message;
|
||||
|
||||
|
||||
private int comment_count;
|
||||
|
||||
public GHAuthor getAuthor() {
|
||||
return author;
|
||||
}
|
||||
private GHVerification verification;
|
||||
|
||||
public GHAuthor getCommitter() {
|
||||
return committer;
|
||||
}
|
||||
static class Tree {
|
||||
String sha;
|
||||
}
|
||||
|
||||
private Tree tree;
|
||||
|
||||
/**
|
||||
* Commit message.
|
||||
* Gets author.
|
||||
*
|
||||
* @return the author
|
||||
*/
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
@WithBridgeMethods(value = GHAuthor.class, castRequired = true)
|
||||
public GitUser getAuthor() {
|
||||
return author;
|
||||
}
|
||||
|
||||
public int getCommentCount() {
|
||||
return comment_count;
|
||||
}
|
||||
}
|
||||
|
||||
public static class GHAuthor {
|
||||
private String name,email,date;
|
||||
/**
|
||||
* Gets authored date.
|
||||
*
|
||||
* @return the authored date
|
||||
*/
|
||||
public Date getAuthoredDate() {
|
||||
return GitHubClient.parseDate(author.date);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
/**
|
||||
* Gets committer.
|
||||
*
|
||||
* @return the committer
|
||||
*/
|
||||
@WithBridgeMethods(value = GHAuthor.class, castRequired = true)
|
||||
public GitUser getCommitter() {
|
||||
return committer;
|
||||
}
|
||||
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
/**
|
||||
* Gets commit date.
|
||||
*
|
||||
* @return the commit date
|
||||
*/
|
||||
public Date getCommitDate() {
|
||||
return GitHubClient.parseDate(committer.date);
|
||||
}
|
||||
|
||||
public Date getDate() {
|
||||
return GitHub.parseDate(date);
|
||||
/**
|
||||
* Gets message.
|
||||
*
|
||||
* @return Commit message.
|
||||
*/
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets comment count.
|
||||
*
|
||||
* @return the comment count
|
||||
*/
|
||||
public int getCommentCount() {
|
||||
return comment_count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets Verification Status.
|
||||
*
|
||||
* @return the Verification status
|
||||
*/
|
||||
public GHVerification getVerification() {
|
||||
return verification;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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")
|
||||
public static class File {
|
||||
String status;
|
||||
int changes,additions,deletions;
|
||||
String raw_url, blob_url, filename, sha, patch;
|
||||
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 "deleted"
|
||||
* Gets status.
|
||||
*
|
||||
* @return "modified", "added", or "removed"
|
||||
*/
|
||||
public String getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Just the base name and the extension without any directory name.
|
||||
* 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")
|
||||
public String getFileName() {
|
||||
return filename;
|
||||
}
|
||||
|
||||
/**
|
||||
* The actual change.
|
||||
* Gets previous filename.
|
||||
*
|
||||
* @return Previous path, in case file has moved.
|
||||
*/
|
||||
public String getPreviousFilename() {
|
||||
return previous_filename;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
return GitHubClient.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);
|
||||
return GitHubClient.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 {
|
||||
String url,sha;
|
||||
@SuppressFBWarnings(value = "UUF_UNUSED_FIELD", justification = "We don't provide it in API now")
|
||||
String url;
|
||||
String sha;
|
||||
}
|
||||
|
||||
static class User {
|
||||
// TODO: what if someone who doesn't have an account on GitHub makes a commit?
|
||||
String url,avatar_url,login,gravatar_id;
|
||||
@SuppressFBWarnings(value = "UUF_UNUSED_FIELD", justification = "We don't provide it in API now")
|
||||
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,sha;
|
||||
String url, html_url, sha;
|
||||
List<File> files;
|
||||
Stats stats;
|
||||
List<Parent> parents;
|
||||
User author,committer;
|
||||
|
||||
|
||||
User author, committer;
|
||||
|
||||
public ShortInfo getCommitShortInfo() {
|
||||
return commit;
|
||||
}
|
||||
/**
|
||||
* Gets commit short info.
|
||||
*
|
||||
* @return the commit short info
|
||||
* @throws IOException
|
||||
* the io exception
|
||||
*/
|
||||
public ShortInfo getCommitShortInfo() throws IOException {
|
||||
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() {
|
||||
public int getLinesChanged() throws IOException {
|
||||
populate();
|
||||
return stats.total;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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() {
|
||||
public int getLinesAdded() throws IOException {
|
||||
populate();
|
||||
return stats.additions;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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() {
|
||||
public int getLinesDeleted() throws IOException {
|
||||
populate();
|
||||
return stats.deletions;
|
||||
}
|
||||
|
||||
/**
|
||||
* [0-9a-f]{40} SHA1 checksum.
|
||||
* 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets html url.
|
||||
*
|
||||
* @return URL of this commit like
|
||||
* "https://github.com/kohsuke/sandbox-ant/commit/8ae38db0ea5837313ab5f39d43a6f73de3bd9000"
|
||||
*/
|
||||
public URL getHtmlUrl() {
|
||||
return GitHubClient.parseURL(html_url);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets sha 1.
|
||||
*
|
||||
* @return [0 -9a-f]{40} SHA1 checksum.
|
||||
*/
|
||||
public String getSHA1() {
|
||||
return sha;
|
||||
@@ -205,18 +352,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() {
|
||||
return files!=null ? Collections.unmodifiableList(files) : Collections.<File>emptyList();
|
||||
public List<File> getFiles() throws IOException {
|
||||
populate();
|
||||
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) {
|
||||
@@ -232,6 +384,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>();
|
||||
@@ -240,69 +396,157 @@ 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.
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
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() {
|
||||
return new PagedIterator<GHCommitComment>(owner.root.retrieve().asIterator(String.format("/repos/%s/%s/commits/%s/comments", owner.getOwnerName(), owner.getName(), sha), GHCommitComment[].class)) {
|
||||
@Override
|
||||
protected void wrapUp(GHCommitComment[] page) {
|
||||
for (GHCommitComment c : page)
|
||||
c.wrap(owner);
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
return owner.root.createRequest()
|
||||
.withUrlPath(
|
||||
String.format("/repos/%s/%s/commits/%s/comments", owner.getOwnerName(), owner.getName(), sha))
|
||||
.toIterable(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 = owner.root.createRequest()
|
||||
.method("POST")
|
||||
.with("body", body)
|
||||
.with("path", path)
|
||||
.with("line", line)
|
||||
.with("position", position)
|
||||
.withUrlPath(
|
||||
String.format("/repos/%s/%s/commits/%s/comments", owner.getOwnerName(), owner.getName(), sha))
|
||||
.fetch(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);
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets check-runs for given sha.
|
||||
*
|
||||
* @return check runs for given sha.
|
||||
* @throws IOException
|
||||
* on error
|
||||
*/
|
||||
@Preview
|
||||
@Deprecated
|
||||
public PagedIterable<GHCheckRun> getCheckRuns() throws IOException {
|
||||
return owner.getCheckRuns(sha);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
owner.root.createRequest().withUrlPath(owner.getApiTailUrl("commits/" + sha)).fetchInto(this);
|
||||
}
|
||||
|
||||
GHCommit wrapUp(GHRepository owner) {
|
||||
this.owner = owner;
|
||||
return this;
|
||||
|
||||
123
src/main/java/org/kohsuke/github/GHCommitBuilder.java
Normal file
123
src/main/java/org/kohsuke/github/GHCommitBuilder.java
Normal file
@@ -0,0 +1,123 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
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
|
||||
*/
|
||||
public class GHCommitBuilder {
|
||||
private final GHRepository repo;
|
||||
private final Requester req;
|
||||
|
||||
private final List<String> parents = new ArrayList<String>();
|
||||
|
||||
private static final class UserInfo {
|
||||
private final String name;
|
||||
private final String email;
|
||||
private final String date;
|
||||
|
||||
private UserInfo(String name, String email, Date date) {
|
||||
this.name = name;
|
||||
this.email = email;
|
||||
TimeZone tz = TimeZone.getTimeZone("UTC");
|
||||
DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
|
||||
df.setTimeZone(tz);
|
||||
this.date = df.format((date != null) ? date : new Date());
|
||||
}
|
||||
}
|
||||
|
||||
GHCommitBuilder(GHRepository repo) {
|
||||
this.repo = repo;
|
||||
req = repo.root.createRequest().method("POST");
|
||||
}
|
||||
|
||||
/**
|
||||
* Message gh commit builder.
|
||||
*
|
||||
* @param message
|
||||
* the commit message
|
||||
* @return the gh commit builder
|
||||
*/
|
||||
public GHCommitBuilder message(String message) {
|
||||
req.with("message", message);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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));
|
||||
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));
|
||||
return this;
|
||||
}
|
||||
|
||||
private String getApiTail() {
|
||||
return String.format("/repos/%s/%s/git/commits", repo.getOwnerName(), repo.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
return req.method("POST").withUrlPath(getApiTail()).fetch(GHCommit.class).wrapUp(repo);
|
||||
}
|
||||
}
|
||||
@@ -1,93 +1,104 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.Date;
|
||||
|
||||
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)
|
||||
*/
|
||||
public class GHCommitComment {
|
||||
@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 updated_at, created_at;
|
||||
String body, url, html_url, commit_id;
|
||||
String body, html_url, commit_id;
|
||||
Integer line;
|
||||
int id;
|
||||
String path;
|
||||
User user;
|
||||
|
||||
static class User {
|
||||
// TODO: what if someone who doesn't have an account on GitHub makes a commit?
|
||||
String url,avatar_url,login,gravatar_id;
|
||||
int id;
|
||||
}
|
||||
GHUser user; // not fully populated. beware.
|
||||
|
||||
/**
|
||||
* Gets owner.
|
||||
*
|
||||
* @return the owner
|
||||
*/
|
||||
public GHRepository getOwner() {
|
||||
return owner;
|
||||
}
|
||||
|
||||
public Date getCreatedAt() {
|
||||
return GitHub.parseDate(created_at);
|
||||
}
|
||||
|
||||
public Date getUpdatedAt() {
|
||||
return GitHub.parseDate(updated_at);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
return GitHubClient.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;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
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.root.getUser(user.login);
|
||||
return owner == null || owner.root.isOffline() ? user : owner.root.getUser(user.login);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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());
|
||||
@@ -95,28 +106,61 @@ public class GHCommitComment {
|
||||
|
||||
/**
|
||||
* Updates the body of the commit message.
|
||||
*
|
||||
* @param body
|
||||
* the body
|
||||
* @throws IOException
|
||||
* the io exception
|
||||
*/
|
||||
public void update(String body) throws IOException {
|
||||
GHCommitComment r = new Requester(owner.root)
|
||||
owner.root.createRequest()
|
||||
.method("PATCH")
|
||||
.with("body", body)
|
||||
.method("PATCH").to(getApiTail(), GHCommitComment.class);
|
||||
.withUrlPath(getApiTail())
|
||||
.fetch(GHCommitComment.class);
|
||||
this.body = body;
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Deprecated
|
||||
public GHReaction createReaction(ReactionContent content) throws IOException {
|
||||
return owner.root.createRequest()
|
||||
.method("POST")
|
||||
.withPreview(SQUIRREL_GIRL)
|
||||
.with("content", content.getContent())
|
||||
.withUrlPath(getApiTail() + "/reactions")
|
||||
.fetch(GHReaction.class)
|
||||
.wrap(owner.root);
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Deprecated
|
||||
public PagedIterable<GHReaction> listReactions() {
|
||||
return owner.root.createRequest()
|
||||
.withPreview(SQUIRREL_GIRL)
|
||||
.withUrlPath(getApiTail() + "/reactions")
|
||||
.toIterable(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());
|
||||
owner.root.createRequest().method("DELETE").withUrlPath(getApiTail()).send();
|
||||
}
|
||||
|
||||
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(), getId());
|
||||
}
|
||||
|
||||
|
||||
GHCommitComment wrap(GHRepository owner) {
|
||||
this.owner = owner;
|
||||
if (owner.root.isOffline()) {
|
||||
user.wrapUp(owner.root);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
*/
|
||||
package org.kohsuke.github;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Identifies a commit in {@link GHPullRequest}.
|
||||
*
|
||||
@@ -31,25 +33,34 @@ package org.kohsuke.github;
|
||||
public class GHCommitPointer {
|
||||
private String ref, sha, label;
|
||||
private GHUser user;
|
||||
private GHRepository repository/*V2*/,repo/*V3*/;
|
||||
private GHRepository repo;
|
||||
|
||||
/**
|
||||
* This points to the user who owns
|
||||
* the {@link #repository}.
|
||||
* This points to the user who owns the {@link #getRepository()}.
|
||||
*
|
||||
* @return the user
|
||||
* @throws IOException
|
||||
* the io exception
|
||||
*/
|
||||
public GHUser getUser() {
|
||||
public GHUser getUser() throws IOException {
|
||||
if (user != null)
|
||||
return user.root.intern(user);
|
||||
return user;
|
||||
}
|
||||
|
||||
/**
|
||||
* The repository that contains the commit.
|
||||
*
|
||||
* @return the repository
|
||||
*/
|
||||
public GHRepository getRepository() {
|
||||
return repo!=null ? repo : repository;
|
||||
return repo;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
@@ -57,6 +68,8 @@ public class GHCommitPointer {
|
||||
|
||||
/**
|
||||
* SHA1 of the commit.
|
||||
*
|
||||
* @return the sha
|
||||
*/
|
||||
public String getSha() {
|
||||
return sha;
|
||||
@@ -64,14 +77,28 @@ public class GHCommitPointer {
|
||||
|
||||
/**
|
||||
* String that looks like "USERNAME:REF".
|
||||
*
|
||||
* @return the label
|
||||
*/
|
||||
public String getLabel() {
|
||||
return label;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 (repository!=null) repository.wrap(root);
|
||||
if (user != null)
|
||||
user.root = root;
|
||||
if (repo != null)
|
||||
repo.wrap(root);
|
||||
}
|
||||
}
|
||||
|
||||
132
src/main/java/org/kohsuke/github/GHCommitQueryBuilder.java
Normal file
132
src/main/java/org/kohsuke/github/GHCommitQueryBuilder.java
Normal file
@@ -0,0 +1,132 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* Builds up query for listing commits.
|
||||
*
|
||||
* <p>
|
||||
* Call various methods that set the filter criteria, then {@link #list()} method to actually list up the commit.
|
||||
*
|
||||
* <pre>
|
||||
* GHRepository r = ...;
|
||||
* for (GHCommit c : r.queryCommits().since(x).until(y).author("kohsuke")) {
|
||||
* ...
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* @author Kohsuke Kawaguchi
|
||||
* @see GHRepository#queryCommits() GHRepository#queryCommits()
|
||||
*/
|
||||
public class GHCommitQueryBuilder {
|
||||
private final Requester req;
|
||||
private final GHRepository repo;
|
||||
|
||||
GHCommitQueryBuilder(GHRepository repo) {
|
||||
this.repo = repo;
|
||||
this.req = repo.root.createRequest(); // 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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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", GitHubClient.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));
|
||||
}
|
||||
|
||||
/**
|
||||
* 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", GitHubClient.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));
|
||||
}
|
||||
|
||||
/**
|
||||
* Lists up the commits with the criteria built so far.
|
||||
*
|
||||
* @return the paged iterable
|
||||
*/
|
||||
public PagedIterable<GHCommit> list() {
|
||||
return req.withUrlPath(repo.getApiTailUrl("commits")).toIterable(GHCommit[].class, item -> item.wrapUp(repo));
|
||||
}
|
||||
}
|
||||
271
src/main/java/org/kohsuke/github/GHCommitSearchBuilder.java
Normal file
271
src/main/java/org/kohsuke/github/GHCommitSearchBuilder.java
Normal file
@@ -0,0 +1,271 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Search commits.
|
||||
*
|
||||
* @author Marc de Verdelhan
|
||||
* @see GitHub#searchCommits() GitHub#searchCommits()
|
||||
*/
|
||||
@Preview
|
||||
@Deprecated
|
||||
public class GHCommitSearchBuilder extends GHSearchBuilder<GHCommit> {
|
||||
GHCommitSearchBuilder(GitHub root) {
|
||||
super(root, CommitSearchResult.class);
|
||||
req.withPreview(Previews.CLOAK);
|
||||
}
|
||||
|
||||
/**
|
||||
* Search terms.
|
||||
*/
|
||||
public GHCommitSearchBuilder q(String term) {
|
||||
super.q(term);
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Committer gh commit search builder.
|
||||
*
|
||||
* @param v
|
||||
* the v
|
||||
* @return the gh commit search builder
|
||||
*/
|
||||
public GHCommitSearchBuilder committer(String 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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());
|
||||
}
|
||||
|
||||
/**
|
||||
* Hash gh commit search builder.
|
||||
*
|
||||
* @param v
|
||||
* the v
|
||||
* @return the gh commit search builder
|
||||
*/
|
||||
public GHCommitSearchBuilder hash(String 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tree gh commit search builder.
|
||||
*
|
||||
* @param v
|
||||
* the v
|
||||
* @return the gh commit search builder
|
||||
*/
|
||||
public GHCommitSearchBuilder tree(String 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* User gh commit search builder.
|
||||
*
|
||||
* @param v
|
||||
* the v
|
||||
* @return the gh commit search builder
|
||||
*/
|
||||
public GHCommitSearchBuilder user(String 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Repo gh commit search builder.
|
||||
*
|
||||
* @param v
|
||||
* the v
|
||||
* @return the gh commit search builder
|
||||
*/
|
||||
public GHCommitSearchBuilder repo(String 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);
|
||||
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);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* The enum Sort.
|
||||
*/
|
||||
public enum Sort {
|
||||
AUTHOR_DATE, COMMITTER_DATE
|
||||
}
|
||||
|
||||
private static class CommitSearchResult extends SearchResult<GHCommit> {
|
||||
private GHCommit[] items;
|
||||
|
||||
@Override
|
||||
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) {
|
||||
}
|
||||
}
|
||||
return items;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param commitUrl
|
||||
* a commit URL
|
||||
* @return the repo name ("username/reponame")
|
||||
*/
|
||||
private static String getRepoName(String commitUrl) {
|
||||
if (StringUtils.isBlank(commitUrl)) {
|
||||
return null;
|
||||
}
|
||||
int indexOfUsername = (GitHubClient.GITHUB_URL + "/repos/").length();
|
||||
String[] tokens = commitUrl.substring(indexOfUsername).split("/", 3);
|
||||
return tokens[0] + '/' + tokens[1];
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getApiUrl() {
|
||||
return "/search/commits";
|
||||
}
|
||||
}
|
||||
@@ -1,72 +1,90 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Date;
|
||||
import java.net.URL;
|
||||
|
||||
/**
|
||||
* Represents a status of a commit.
|
||||
*
|
||||
* @author Kohsuke Kawaguchi
|
||||
* @see GHRepository#getCommitStatus(String)
|
||||
* @see GHCommit#getStatus()
|
||||
* @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 {
|
||||
String created_at, updated_at;
|
||||
public class GHCommitStatus extends GHObject {
|
||||
String state;
|
||||
String target_url,description;
|
||||
int id;
|
||||
String url;
|
||||
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;
|
||||
}
|
||||
|
||||
public Date getCreatedAt() {
|
||||
return GitHub.parseDate(created_at);
|
||||
}
|
||||
|
||||
public Date getUpdatedAt() {
|
||||
return GitHub.parseDate(updated_at);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
/**
|
||||
* Gets creator.
|
||||
*
|
||||
* @return the creator
|
||||
* @throws IOException
|
||||
* the io exception
|
||||
*/
|
||||
public GHUser getCreator() throws IOException {
|
||||
return root.intern(creator);
|
||||
}
|
||||
|
||||
/**
|
||||
* API URL of this commit status.
|
||||
* Gets context.
|
||||
*
|
||||
* @return the context
|
||||
*/
|
||||
public String getUrl() {
|
||||
return url;
|
||||
public String getContext() {
|
||||
return context;
|
||||
}
|
||||
|
||||
public GHUser getCreator() {
|
||||
return creator;
|
||||
/**
|
||||
* @deprecated This object has no HTML URL.
|
||||
*/
|
||||
@Override
|
||||
public URL getHtmlUrl() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
import com.infradna.tool.bridge_method_injector.WithBridgeMethods;
|
||||
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* The model user for comparing 2 commits in the GitHub API.
|
||||
@@ -19,55 +21,134 @@ public class GHCompare {
|
||||
|
||||
private GHRepository owner;
|
||||
|
||||
/**
|
||||
* Gets url.
|
||||
*
|
||||
* @return the url
|
||||
*/
|
||||
public URL getUrl() {
|
||||
return GitHub.parseURL(url);
|
||||
return GitHubClient.parseURL(url);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets html url.
|
||||
*
|
||||
* @return the html url
|
||||
*/
|
||||
public URL getHtmlUrl() {
|
||||
return GitHub.parseURL(html_url);
|
||||
return GitHubClient.parseURL(html_url);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets permalink url.
|
||||
*
|
||||
* @return the permalink url
|
||||
*/
|
||||
public URL getPermalinkUrl() {
|
||||
return GitHub.parseURL(permalink_url);
|
||||
return GitHubClient.parseURL(permalink_url);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets diff url.
|
||||
*
|
||||
* @return the diff url
|
||||
*/
|
||||
public URL getDiffUrl() {
|
||||
return GitHub.parseURL(diff_url);
|
||||
return GitHubClient.parseURL(diff_url);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets patch url.
|
||||
*
|
||||
* @return the patch url
|
||||
*/
|
||||
public URL getPatchUrl() {
|
||||
return GitHub.parseURL(patch_url);
|
||||
return GitHubClient.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() {
|
||||
return commits;
|
||||
Commit[] newValue = new Commit[commits.length];
|
||||
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() {
|
||||
GHCommit.File[] newValue = new GHCommit.File[files.length];
|
||||
System.arraycopy(files, 0, newValue, 0, files.length);
|
||||
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) {
|
||||
@@ -79,78 +160,127 @@ 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" },
|
||||
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;
|
||||
}
|
||||
|
||||
public User getAuthor() {
|
||||
/**
|
||||
* Gets author.
|
||||
*
|
||||
* @return the author
|
||||
*/
|
||||
@WithBridgeMethods(value = User.class, castRequired = true)
|
||||
public GitUser getAuthor() {
|
||||
return author;
|
||||
}
|
||||
|
||||
public User getCommitter() {
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
|
||||
public static class User {
|
||||
private String name, email, date;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
public Date getDate() {
|
||||
return GitHub.parseDate(date);
|
||||
}
|
||||
/**
|
||||
* The type User.
|
||||
*
|
||||
* @deprecated use {@link GitUser} instead.
|
||||
*/
|
||||
public static class User extends GitUser {
|
||||
}
|
||||
|
||||
/**
|
||||
* The enum Status.
|
||||
*/
|
||||
public static enum Status {
|
||||
behind, ahead, identical;
|
||||
behind, ahead, identical, diverged
|
||||
}
|
||||
}
|
||||
|
||||
400
src/main/java/org/kohsuke/github/GHContent.java
Normal file
400
src/main/java/org/kohsuke/github/GHContent.java
Normal file
@@ -0,0 +1,400 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Base64;
|
||||
|
||||
/**
|
||||
* A Content of a repository.
|
||||
*
|
||||
* @author Alexandre COLLIGNON
|
||||
* @see GHRepository#getFileContent(String) GHRepository#getFileContent(String)
|
||||
*/
|
||||
@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.
|
||||
*/
|
||||
private GHRepository repository;
|
||||
|
||||
private GitHub root;
|
||||
|
||||
private String type;
|
||||
private String encoding;
|
||||
private long size;
|
||||
private String sha;
|
||||
private String name;
|
||||
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 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @return the content
|
||||
* @throws IOException
|
||||
* the io exception
|
||||
* @deprecated Use {@link #read()}
|
||||
*/
|
||||
@SuppressFBWarnings("DM_DEFAULT_ENCODING")
|
||||
public String getContent() throws IOException {
|
||||
return new String(Base64.getMimeDecoder().decode(getEncodedContent()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @return the encoded content
|
||||
* @throws IOException
|
||||
* the io exception
|
||||
* @deprecated Use {@link #read()}
|
||||
*/
|
||||
public String getEncodedContent() throws IOException {
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 {
|
||||
refresh(content);
|
||||
if (encoding.equals("base64")) {
|
||||
try {
|
||||
Base64.Decoder decoder = Base64.getMimeDecoder();
|
||||
return new ByteArrayInputStream(decoder.decode(content.getBytes(StandardCharsets.US_ASCII)));
|
||||
} catch (IllegalArgumentException 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 {
|
||||
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 {
|
||||
root.createRequest().withUrlPath(url).fetchInto(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");
|
||||
|
||||
return root.createRequest().setRawUrlPath(url).toIterable(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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.getEncoder().encodeToString(newContentBytes);
|
||||
|
||||
Requester requester = root.createRequest()
|
||||
.method("POST")
|
||||
.with("path", path)
|
||||
.with("message", commitMessage)
|
||||
.with("sha", sha)
|
||||
.with("content", encodedContent)
|
||||
.method("PUT");
|
||||
|
||||
if (branch != null) {
|
||||
requester.with("branch", branch);
|
||||
}
|
||||
|
||||
GHContentUpdateResponse response = requester.withUrlPath(getApiRoute(repository, path))
|
||||
.fetch(GHContentUpdateResponse.class);
|
||||
|
||||
response.getContent().wrap(repository);
|
||||
response.getCommit().wrapUp(repository);
|
||||
|
||||
this.content = encodedContent;
|
||||
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 = root.createRequest()
|
||||
.method("POST")
|
||||
.with("path", path)
|
||||
.with("message", commitMessage)
|
||||
.with("sha", sha)
|
||||
.method("DELETE");
|
||||
|
||||
if (branch != null) {
|
||||
requester.with("branch", branch);
|
||||
}
|
||||
|
||||
GHContentUpdateResponse response = requester.withUrlPath(getApiRoute(repository, path))
|
||||
.fetch(GHContentUpdateResponse.class);
|
||||
|
||||
response.getCommit().wrapUp(repository);
|
||||
return response;
|
||||
}
|
||||
|
||||
static String getApiRoute(GHRepository repository, String path) {
|
||||
return repository.getApiTailUrl("contents/" + path);
|
||||
}
|
||||
|
||||
GHContent wrap(GHRepository owner) {
|
||||
this.repository = owner;
|
||||
this.root = owner.root;
|
||||
return this;
|
||||
}
|
||||
|
||||
GHContent wrap(GitHub root) {
|
||||
this.root = root;
|
||||
if (repository != null)
|
||||
repository.wrap(root);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.createRequest().setRawUrlPath(url).fetchInto(this);
|
||||
}
|
||||
}
|
||||
114
src/main/java/org/kohsuke/github/GHContentBuilder.java
Normal file
114
src/main/java/org/kohsuke/github/GHContentBuilder.java
Normal file
@@ -0,0 +1,114 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Base64;
|
||||
|
||||
/**
|
||||
* 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 = repo.root.createRequest().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 the blob 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.getEncoder().encodeToString(content));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Content gh content builder.
|
||||
*
|
||||
* @param content
|
||||
* the content
|
||||
* @return the gh content builder
|
||||
*/
|
||||
public GHContentBuilder content(String content) {
|
||||
return content(content.getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.withUrlPath(GHContent.getApiRoute(repo, path))
|
||||
.fetch(GHContentUpdateResponse.class);
|
||||
|
||||
response.getContent().wrap(repo);
|
||||
response.getCommit().wrapUp(repo);
|
||||
|
||||
return response;
|
||||
}
|
||||
}
|
||||
136
src/main/java/org/kohsuke/github/GHContentSearchBuilder.java
Normal file
136
src/main/java/org/kohsuke/github/GHContentSearchBuilder.java
Normal file
@@ -0,0 +1,136 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
/**
|
||||
* Search code for {@link GHContent}.
|
||||
*
|
||||
* @author Kohsuke Kawaguchi
|
||||
* @see GitHub#searchContent() GitHub#searchContent()
|
||||
*/
|
||||
public class GHContentSearchBuilder extends GHSearchBuilder<GHContent> {
|
||||
GHContentSearchBuilder(GitHub root) {
|
||||
super(root, ContentSearchResult.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Search terms.
|
||||
*/
|
||||
public GHContentSearchBuilder q(String term) {
|
||||
super.q(term);
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Language gh content search builder.
|
||||
*
|
||||
* @param v
|
||||
* the v
|
||||
* @return the gh content search builder
|
||||
*/
|
||||
public GHContentSearchBuilder language(String 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Size gh content search builder.
|
||||
*
|
||||
* @param v
|
||||
* the v
|
||||
* @return the gh content search builder
|
||||
*/
|
||||
public GHContentSearchBuilder size(String 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filename gh content search builder.
|
||||
*
|
||||
* @param v
|
||||
* the v
|
||||
* @return the gh content search builder
|
||||
*/
|
||||
public GHContentSearchBuilder filename(String 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* User gh content search builder.
|
||||
*
|
||||
* @param v
|
||||
* the v
|
||||
* @return the gh content search builder
|
||||
*/
|
||||
public GHContentSearchBuilder user(String 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);
|
||||
}
|
||||
|
||||
private static class ContentSearchResult extends SearchResult<GHContent> {
|
||||
private GHContent[] items;
|
||||
|
||||
@Override
|
||||
GHContent[] getItems(GitHub root) {
|
||||
for (GHContent item : items)
|
||||
item.wrap(root);
|
||||
return items;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getApiUrl() {
|
||||
return "/search/code";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
20
src/main/java/org/kohsuke/github/GHContentWithLicense.java
Normal file
20
src/main/java/org/kohsuke/github/GHContentWithLicense.java
Normal file
@@ -0,0 +1,20 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
/**
|
||||
* {@link GHContent} with license information.
|
||||
*
|
||||
* @author Kohsuke Kawaguchi
|
||||
* @see <a href="https://developer.github.com/v3/licenses/#get-a-repositorys-license">documentation</a>
|
||||
* @see GHRepository#getLicense()
|
||||
*/
|
||||
class GHContentWithLicense extends GHContent {
|
||||
GHLicense license;
|
||||
|
||||
@Override
|
||||
GHContentWithLicense wrap(GHRepository owner) {
|
||||
super.wrap(owner);
|
||||
if (license != null)
|
||||
license.wrap(owner.root);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
214
src/main/java/org/kohsuke/github/GHCreateRepositoryBuilder.java
Normal file
214
src/main/java/org/kohsuke/github/GHCreateRepositoryBuilder.java
Normal file
@@ -0,0 +1,214 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
|
||||
/**
|
||||
* Creates a repository
|
||||
*
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
public class GHCreateRepositoryBuilder {
|
||||
private final GitHub root;
|
||||
protected final Requester builder;
|
||||
private final String apiUrlTail;
|
||||
|
||||
GHCreateRepositoryBuilder(GitHub root, String apiUrlTail, String name) {
|
||||
this.root = root;
|
||||
this.apiUrlTail = apiUrlTail;
|
||||
this.builder = root.createRequest();
|
||||
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);
|
||||
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);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a private repository
|
||||
*
|
||||
* @param enabled
|
||||
* private if true
|
||||
* @return a builder to continue with building
|
||||
*/
|
||||
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 enabled) {
|
||||
this.builder.with("has_issues", enabled);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables projects
|
||||
*
|
||||
* @param enabled
|
||||
* true if enabled
|
||||
* @return a builder to continue with building
|
||||
*/
|
||||
public GHCreateRepositoryBuilder projects(boolean enabled) {
|
||||
this.builder.with("has_projects", enabled);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables wiki
|
||||
*
|
||||
* @param enabled
|
||||
* true if enabled
|
||||
* @return a builder to continue with building
|
||||
*/
|
||||
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 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 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 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 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 enabled) {
|
||||
this.builder.with("allow_rebase_merge", enabled);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a default .gitignore
|
||||
*
|
||||
* @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);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Desired license template to apply
|
||||
*
|
||||
* @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);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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());
|
||||
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").withUrlPath(apiUrlTail).fetch(GHRepository.class).wrap(root);
|
||||
}
|
||||
|
||||
}
|
||||
90
src/main/java/org/kohsuke/github/GHDeployKey.java
Normal file
90
src/main/java/org/kohsuke/github/GHDeployKey.java
Normal file
@@ -0,0 +1,90 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
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 long id;
|
||||
private GHRepository owner;
|
||||
|
||||
/**
|
||||
* 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();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete.
|
||||
*
|
||||
* @throws IOException
|
||||
* the io exception
|
||||
*/
|
||||
public void delete() throws IOException {
|
||||
owner.root.createRequest()
|
||||
.method("DELETE")
|
||||
.withUrlPath(String.format("/repos/%s/%s/keys/%d", owner.getOwnerName(), owner.getName(), id))
|
||||
.send();
|
||||
}
|
||||
}
|
||||
139
src/main/java/org/kohsuke/github/GHDeployment.java
Normal file
139
src/main/java/org/kohsuke/github/GHDeployment.java
Normal file
@@ -0,0 +1,139 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
import java.io.IOException;
|
||||
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) GHRepository#listDeployments(String, String,
|
||||
* String, String)
|
||||
* @see GHRepository#getDeployment(long) GHRepository#getDeployment(long)
|
||||
*/
|
||||
public class GHDeployment extends GHObject {
|
||||
private GHRepository owner;
|
||||
private GitHub root;
|
||||
protected String sha;
|
||||
protected String ref;
|
||||
protected String task;
|
||||
protected Object payload;
|
||||
protected String environment;
|
||||
protected String description;
|
||||
protected String statuses_url;
|
||||
protected String repository_url;
|
||||
protected GHUser creator;
|
||||
|
||||
GHDeployment wrap(GHRepository owner) {
|
||||
this.owner = owner;
|
||||
this.root = owner.root;
|
||||
if (creator != null)
|
||||
creator.wrapUp(root);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets statuses url.
|
||||
*
|
||||
* @return the statuses url
|
||||
*/
|
||||
public URL getStatusesUrl() {
|
||||
return GitHubClient.parseURL(statuses_url);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets repository url.
|
||||
*
|
||||
* @return the repository url
|
||||
*/
|
||||
public URL getRepositoryUrl() {
|
||||
return GitHubClient.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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets sha.
|
||||
*
|
||||
* @return the sha
|
||||
*/
|
||||
public String getSha() {
|
||||
return sha;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated This object has no HTML URL.
|
||||
*/
|
||||
@Override
|
||||
public URL getHtmlUrl() {
|
||||
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, getId(), state);
|
||||
}
|
||||
|
||||
/**
|
||||
* List statuses paged iterable.
|
||||
*
|
||||
* @return the paged iterable
|
||||
*/
|
||||
public PagedIterable<GHDeploymentStatus> listStatuses() {
|
||||
return root.createRequest()
|
||||
.withUrlPath(statuses_url)
|
||||
.toIterable(GHDeploymentStatus[].class, item -> item.wrap(owner));
|
||||
}
|
||||
|
||||
}
|
||||
132
src/main/java/org/kohsuke/github/GHDeploymentBuilder.java
Normal file
132
src/main/java/org/kohsuke/github/GHDeploymentBuilder.java
Normal file
@@ -0,0 +1,132 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 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 = repo.root.createRequest().method("POST");
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Task gh deployment builder.
|
||||
*
|
||||
* @param task
|
||||
* the task
|
||||
* @return the gh deployment builder
|
||||
*/
|
||||
public GHDeploymentBuilder task(String 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);
|
||||
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);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Payload gh deployment builder.
|
||||
*
|
||||
* @param payload
|
||||
* the payload
|
||||
* @return the gh deployment builder
|
||||
*/
|
||||
public GHDeploymentBuilder payload(String 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.withUrlPath(repo.getApiTailUrl("deployments")).fetch(GHDeployment.class).wrap(repo);
|
||||
}
|
||||
}
|
||||
8
src/main/java/org/kohsuke/github/GHDeploymentState.java
Normal file
8
src/main/java/org/kohsuke/github/GHDeploymentState.java
Normal file
@@ -0,0 +1,8 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
/**
|
||||
* Represents the state of deployment
|
||||
*/
|
||||
public enum GHDeploymentState {
|
||||
PENDING, SUCCESS, ERROR, FAILURE
|
||||
}
|
||||
77
src/main/java/org/kohsuke/github/GHDeploymentStatus.java
Normal file
77
src/main/java/org/kohsuke/github/GHDeploymentStatus.java
Normal file
@@ -0,0 +1,77 @@
|
||||
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;
|
||||
protected GHUser creator;
|
||||
protected String state;
|
||||
protected String description;
|
||||
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);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets target url.
|
||||
*
|
||||
* @return the target url
|
||||
*/
|
||||
public URL getTargetUrl() {
|
||||
return GitHubClient.parseURL(target_url);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets deployment url.
|
||||
*
|
||||
* @return the deployment url
|
||||
*/
|
||||
public URL getDeploymentUrl() {
|
||||
return GitHubClient.parseURL(deployment_url);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets repository url.
|
||||
*
|
||||
* @return the repository url
|
||||
*/
|
||||
public URL getRepositoryUrl() {
|
||||
return GitHubClient.parseURL(repository_url);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets state.
|
||||
*
|
||||
* @return the state
|
||||
*/
|
||||
public GHDeploymentState getState() {
|
||||
return GHDeploymentState.valueOf(state.toUpperCase(Locale.ENGLISH));
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated This object has no HTML URL.
|
||||
*/
|
||||
@Override
|
||||
public URL getHtmlUrl() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Creates a new deployment status.
|
||||
*
|
||||
* @see GHDeployment#createStatus(GHDeploymentState) GHDeployment#createStatus(GHDeploymentState)
|
||||
*/
|
||||
public class GHDeploymentStatusBuilder {
|
||||
private final Requester builder;
|
||||
private GHRepository repo;
|
||||
private long deploymentId;
|
||||
|
||||
/**
|
||||
* 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)}
|
||||
*/
|
||||
@Deprecated
|
||||
public GHDeploymentStatusBuilder(GHRepository repo, int deploymentId, GHDeploymentState state) {
|
||||
this(repo, (long) deploymentId, state);
|
||||
}
|
||||
|
||||
GHDeploymentStatusBuilder(GHRepository repo, long deploymentId, GHDeploymentState state) {
|
||||
this.repo = repo;
|
||||
this.deploymentId = deploymentId;
|
||||
this.builder = repo.root.createRequest().method("POST");
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.withUrlPath(repo.getApiTailUrl("deployments/" + deploymentId + "/statuses"))
|
||||
.fetch(GHDeploymentStatus.class)
|
||||
.wrap(repo);
|
||||
}
|
||||
}
|
||||
10
src/main/java/org/kohsuke/github/GHDirection.java
Normal file
10
src/main/java/org/kohsuke/github/GHDirection.java
Normal file
@@ -0,0 +1,10 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
/**
|
||||
* Sort direction
|
||||
*
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
public enum GHDirection {
|
||||
ASC, DESC
|
||||
}
|
||||
88
src/main/java/org/kohsuke/github/GHEmail.java
Normal file
88
src/main/java/org/kohsuke/github/GHEmail.java
Normal file
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright (c) 2010, Kohsuke Kawaguchi
|
||||
*
|
||||
* 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 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")
|
||||
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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return email.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof GHEmail) {
|
||||
GHEmail that = (GHEmail) obj;
|
||||
return this.email.equals(that.email);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,28 +1,79 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* Hook event type.
|
||||
*
|
||||
* See http://developer.github.com/v3/events/types/
|
||||
*
|
||||
* @author Kohsuke Kawaguchi
|
||||
* @see GHEventInfo
|
||||
* @see <a href="https://developer.github.com/v3/activity/events/types/">Event type reference</a>
|
||||
*/
|
||||
public enum GHEvent {
|
||||
CHECK_RUN,
|
||||
CHECK_SUITE,
|
||||
COMMIT_COMMENT,
|
||||
CONTENT_REFERENCE,
|
||||
CREATE,
|
||||
DELETE,
|
||||
DEPLOY_KEY,
|
||||
DEPLOYMENT,
|
||||
DEPLOYMENT_STATUS,
|
||||
DOWNLOAD,
|
||||
FOLLOW,
|
||||
FORK,
|
||||
FORK_APPLY,
|
||||
GITHUB_APP_AUTHORIZATION,
|
||||
GIST,
|
||||
GOLLUM,
|
||||
INSTALLATION,
|
||||
INSTALLATION_REPOSITORIES,
|
||||
INTEGRATION_INSTALLATION_REPOSITORIES,
|
||||
ISSUE_COMMENT,
|
||||
ISSUES,
|
||||
LABEL,
|
||||
MARKETPLACE_PURCHASE,
|
||||
MEMBER,
|
||||
MEMBERSHIP,
|
||||
META,
|
||||
MILESTONE,
|
||||
ORGANIZATION,
|
||||
ORG_BLOCK,
|
||||
PACKAGE,
|
||||
PAGE_BUILD,
|
||||
PROJECT_CARD,
|
||||
PROJECT_COLUMN,
|
||||
PROJECT,
|
||||
PING,
|
||||
PUBLIC,
|
||||
PULL_REQUEST,
|
||||
PULL_REQUEST_REVIEW,
|
||||
PULL_REQUEST_REVIEW_COMMENT,
|
||||
PUSH,
|
||||
REGISTRY_PACKAGE,
|
||||
RELEASE,
|
||||
REPOSITORY_DISPATCH, // only valid for org hooks
|
||||
REPOSITORY,
|
||||
REPOSITORY_IMPORT,
|
||||
REPOSITORY_VULNERABILITY_ALERT,
|
||||
SECURITY_ADVISORY,
|
||||
STAR,
|
||||
STATUS,
|
||||
TEAM,
|
||||
TEAM_ADD,
|
||||
WATCH
|
||||
WATCH,
|
||||
|
||||
/**
|
||||
* Special event type that means "every possible event"
|
||||
*/
|
||||
ALL;
|
||||
|
||||
/**
|
||||
* Returns GitHub's internal representation of this event.
|
||||
*/
|
||||
String symbol() {
|
||||
if (this == ALL)
|
||||
return "*";
|
||||
return name().toLowerCase(Locale.ENGLISH);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,21 +1,24 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Date;
|
||||
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
|
||||
/**
|
||||
* Represents an event.
|
||||
*
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
@SuppressFBWarnings(value = "UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", justification = "JSON API")
|
||||
public class GHEventInfo {
|
||||
private GitHub root;
|
||||
|
||||
// we don't want to expose Jackson dependency to the user. This needs databinding
|
||||
private ObjectNode payload;
|
||||
|
||||
private long id;
|
||||
private String created_at;
|
||||
private String type;
|
||||
|
||||
@@ -27,55 +30,121 @@ 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")
|
||||
public static class GHEventRepository {
|
||||
private int id;
|
||||
private String url; // repository API URL
|
||||
private String name; // owner/repo
|
||||
@SuppressFBWarnings(value = "UUF_UNUSED_FIELD", justification = "We don't provide it in API now")
|
||||
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
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
public Date getCreatedAt() {
|
||||
return GitHub.parseDate(created_at);
|
||||
/**
|
||||
* Gets id.
|
||||
*
|
||||
* @return the id
|
||||
*/
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Repository where the change was made.
|
||||
* Gets created at.
|
||||
*
|
||||
* @return the created at
|
||||
*/
|
||||
public Date getCreatedAt() {
|
||||
return GitHubClient.parseDate(created_at);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets repository.
|
||||
*
|
||||
* @return Repository where the change was made.
|
||||
* @throws IOException
|
||||
* on error
|
||||
*/
|
||||
@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);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets actor login.
|
||||
*
|
||||
* @return the login of the actor.
|
||||
* @throws IOException
|
||||
* on error
|
||||
*/
|
||||
public String getActorLogin() throws IOException {
|
||||
return actor.getLogin();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
T v = GitHubClient.getMappingObjectReader(root).readValue(payload.traverse(), type);
|
||||
v.wrapUp(root);
|
||||
return v;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.annotation.CheckForNull;
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
/**
|
||||
* 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 message
|
||||
* the message
|
||||
*/
|
||||
public GHFileNotFoundException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates a new Gh file not found exception.
|
||||
*
|
||||
* @param message
|
||||
* the message
|
||||
* @param cause
|
||||
* the cause
|
||||
*/
|
||||
public GHFileNotFoundException(String message, Throwable cause) {
|
||||
super(message);
|
||||
this.initCause(cause);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets response header fields.
|
||||
*
|
||||
* @return the response header fields
|
||||
*/
|
||||
@CheckForNull
|
||||
public Map<String, List<String>> getResponseHeaderFields() {
|
||||
return responseHeaderFields;
|
||||
}
|
||||
|
||||
GHFileNotFoundException withResponseHeaderFields(@Nonnull Map<String, List<String>> headerFields) {
|
||||
this.responseHeaderFields = headerFields;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
284
src/main/java/org/kohsuke/github/GHGist.java
Normal file
284
src/main/java/org/kohsuke/github/GHGist.java
Normal file
@@ -0,0 +1,284 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JacksonInject;
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
/**
|
||||
* Gist
|
||||
*
|
||||
* @author Kohsuke Kawaguchi
|
||||
* @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 {
|
||||
|
||||
final GHUser owner;
|
||||
final GitHub root;
|
||||
|
||||
private String forks_url, commits_url, id, git_pull_url, git_push_url, html_url;
|
||||
|
||||
@JsonProperty("public")
|
||||
private boolean _public;
|
||||
|
||||
private String description;
|
||||
|
||||
private int comments;
|
||||
|
||||
private String comments_url;
|
||||
|
||||
private final Map<String, GHGistFile> files;
|
||||
|
||||
@JsonCreator
|
||||
private GHGist(@JacksonInject GitHub root,
|
||||
@JsonProperty("owner") GHUser owner,
|
||||
@JsonProperty("files") Map<String, GHGistFile> files) {
|
||||
this.root = root;
|
||||
for (Entry<String, GHGistFile> e : files.entrySet()) {
|
||||
e.getValue().fileName = e.getKey();
|
||||
}
|
||||
this.files = Collections.unmodifiableMap(files);
|
||||
this.owner = root.getUser(owner);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unlike most other GitHub objects, the id for Gists can be non-numeric, such as "aa5a315d61ae9438b18d". If the id
|
||||
* is numeric, this method will get it. If id is not numeric, this will throw a runtime
|
||||
* {@link NumberFormatException}.
|
||||
*
|
||||
* @return id of the Gist.
|
||||
* @deprecated Use {@link #getGistId()} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
@Override
|
||||
public long getId() {
|
||||
return Long.parseLong(getGistId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the id for this Gist. Unlike most other GitHub objects, the id for Gists can be non-numeric, such as
|
||||
* "aa5a315d61ae9438b18d". This should be used instead of {@link #getId()}.
|
||||
*
|
||||
* @return id of this Gist
|
||||
*/
|
||||
public String getGistId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets owner.
|
||||
*
|
||||
* @return User that owns this Gist.
|
||||
* @throws IOException
|
||||
* the io exception
|
||||
*/
|
||||
public GHUser getOwner() throws IOException {
|
||||
return 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the html url.
|
||||
*
|
||||
* @return the github html url
|
||||
*/
|
||||
public URL getHtmlUrl() {
|
||||
return GitHubClient.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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets files.
|
||||
*
|
||||
* @return the files
|
||||
*/
|
||||
public Map<String, GHGistFile> getFiles() {
|
||||
return files;
|
||||
}
|
||||
|
||||
String getApiTailUrl(String 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 {
|
||||
root.createRequest().method("PUT").withUrlPath(getApiTailUrl("star")).send();
|
||||
}
|
||||
|
||||
/**
|
||||
* Unstar.
|
||||
*
|
||||
* @throws IOException
|
||||
* the io exception
|
||||
*/
|
||||
public void unstar() throws IOException {
|
||||
root.createRequest().method("DELETE").withUrlPath(getApiTailUrl("star")).send();
|
||||
}
|
||||
|
||||
/**
|
||||
* Is starred boolean.
|
||||
*
|
||||
* @return the boolean
|
||||
* @throws IOException
|
||||
* the io exception
|
||||
*/
|
||||
public boolean isStarred() throws IOException {
|
||||
return root.createRequest().withUrlPath(getApiTailUrl("star")).fetchHttpStatusCode() / 100 == 2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Forks this gist into your own.
|
||||
*
|
||||
* @return the gh gist
|
||||
* @throws IOException
|
||||
* the io exception
|
||||
*/
|
||||
public GHGist fork() throws IOException {
|
||||
return root.createRequest().method("POST").withUrlPath(getApiTailUrl("forks")).fetch(GHGist.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* List forks paged iterable.
|
||||
*
|
||||
* @return the paged iterable
|
||||
*/
|
||||
public PagedIterable<GHGist> listForks() {
|
||||
return root.createRequest().withUrlPath(getApiTailUrl("forks")).toIterable(GHGist[].class, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes this gist.
|
||||
*
|
||||
* @throws IOException
|
||||
* the io exception
|
||||
*/
|
||||
public void delete() throws IOException {
|
||||
root.createRequest().method("DELETE").withUrlPath("/gists/" + id).send();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
GHGist ghGist = (GHGist) o;
|
||||
return id.equals(ghGist.id);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return id.hashCode();
|
||||
}
|
||||
}
|
||||
80
src/main/java/org/kohsuke/github/GHGistBuilder.java
Normal file
80
src/main/java/org/kohsuke/github/GHGistBuilder.java
Normal file
@@ -0,0 +1,80 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
/**
|
||||
* Builder pattern for creating a new Gist.
|
||||
*
|
||||
* @author Kohsuke Kawaguchi
|
||||
* @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>();
|
||||
|
||||
/**
|
||||
* Instantiates a new Gh gist builder.
|
||||
*
|
||||
* @param root
|
||||
* the root
|
||||
*/
|
||||
public GHGistBuilder(GitHub root) {
|
||||
this.root = root;
|
||||
req = root.createRequest().method("POST");
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 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(@Nonnull String fileName, @Nonnull String content) {
|
||||
files.put(fileName, Collections.singletonMap("content", content));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.withUrlPath("/gists").fetch(GHGist.class);
|
||||
}
|
||||
}
|
||||
79
src/main/java/org/kohsuke/github/GHGistFile.java
Normal file
79
src/main/java/org/kohsuke/github/GHGistFile.java
Normal file
@@ -0,0 +1,79 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
/**
|
||||
* A file inside {@link GHGist}
|
||||
*
|
||||
* @author Kohsuke Kawaguchi
|
||||
* @see GHGist#getFile(String) GHGist#getFile(String)
|
||||
* @see GHGist#getFiles() GHGist#getFiles()
|
||||
*/
|
||||
public class GHGistFile {
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* URL that serves this file as-is.
|
||||
*
|
||||
* @return the raw url
|
||||
*/
|
||||
public String getRawUrl() {
|
||||
return raw_url;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* (?) indicates if {@link #getContent()} contains a truncated content.
|
||||
*
|
||||
* @return the boolean
|
||||
*/
|
||||
public boolean isTruncated() {
|
||||
return truncated;
|
||||
}
|
||||
}
|
||||
127
src/main/java/org/kohsuke/github/GHGistUpdater.java
Normal file
127
src/main/java/org/kohsuke/github/GHGistUpdater.java
Normal file
@@ -0,0 +1,127 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
/**
|
||||
* Builder pattern for updating a Gist.
|
||||
*
|
||||
* @author Martin van Zijl
|
||||
*/
|
||||
public class GHGistUpdater {
|
||||
private final GHGist base;
|
||||
private final Requester builder;
|
||||
LinkedHashMap<String, Map<String, String>> files;
|
||||
|
||||
GHGistUpdater(GHGist base) {
|
||||
this.base = base;
|
||||
this.builder = base.root.createRequest();
|
||||
|
||||
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(@Nonnull String fileName, @Nonnull String content) throws IOException {
|
||||
updateFile(fileName, content);
|
||||
return this;
|
||||
}
|
||||
|
||||
public GHGistUpdater deleteFile(@Nonnull String fileName) throws IOException {
|
||||
files.put(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(@Nonnull String fileName, @Nonnull String newFileName) throws IOException {
|
||||
Map<String, String> file = files.computeIfAbsent(fileName, d -> new HashMap<>());
|
||||
file.put("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(@Nonnull String fileName, @Nonnull String content) throws IOException {
|
||||
Map<String, String> file = files.computeIfAbsent(fileName, d -> new HashMap<>());
|
||||
file.put("content", content);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update file name and content
|
||||
*
|
||||
* @param fileName
|
||||
* the file name
|
||||
* @param newFileName
|
||||
* the new file name
|
||||
* @param content
|
||||
* the content
|
||||
* @return the gh gist updater
|
||||
* @throws IOException
|
||||
* the io exception
|
||||
*/
|
||||
public GHGistUpdater updateFile(@Nonnull String fileName, @Nonnull String newFileName, @Nonnull String content)
|
||||
throws IOException {
|
||||
Map<String, String> file = files.computeIfAbsent(fileName, d -> new HashMap<>());
|
||||
file.put("content", content);
|
||||
file.put("filename", newFileName);
|
||||
files.put(fileName, file);
|
||||
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").withUrlPath(base.getApiTailUrl("")).fetch(GHGist.class);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,9 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
@@ -8,52 +11,91 @@ import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* The type GHHook.
|
||||
*
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
public final class GHHook {
|
||||
/**
|
||||
* Repository that the hook belongs to.
|
||||
*/
|
||||
/*package*/ transient GHRepository repository;
|
||||
|
||||
String created_at, updated_at, name;
|
||||
@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;
|
||||
int id;
|
||||
|
||||
/*package*/ GHHook wrap(GHRepository owner) {
|
||||
this.repository = owner;
|
||||
return this;
|
||||
}
|
||||
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)
|
||||
Enum.valueOf(GHEvent.class,e.toUpperCase(Locale.ENGLISH));
|
||||
for (String e : events) {
|
||||
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);
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
/**
|
||||
* 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 {
|
||||
getRoot().createRequest().method("POST").withUrlPath(getApiRoute() + "/pings").send();
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes this hook.
|
||||
*
|
||||
* @throws IOException
|
||||
* the io exception
|
||||
*/
|
||||
public void delete() throws IOException {
|
||||
new Requester(repository.root).method("DELETE").to(String.format("/repos/%s/%s/hooks/%d", repository.getOwnerName(), repository.getName(), id));
|
||||
getRoot().createRequest().method("DELETE").withUrlPath(getApiRoute()).send();
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated This object has no HTML URL.
|
||||
*/
|
||||
@Override
|
||||
public URL getHtmlUrl() {
|
||||
return null;
|
||||
}
|
||||
|
||||
abstract GitHub getRoot();
|
||||
|
||||
abstract String getApiRoute();
|
||||
}
|
||||
|
||||
167
src/main/java/org/kohsuke/github/GHHooks.java
Normal file
167
src/main/java/org/kohsuke/github/GHHooks.java
Normal file
@@ -0,0 +1,167 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Utility class for creating and retrieving webhooks; removes duplication between GHOrganization and GHRepository
|
||||
* functionality
|
||||
*/
|
||||
class GHHooks {
|
||||
static abstract class Context {
|
||||
private final GitHub root;
|
||||
|
||||
private Context(GitHub root) {
|
||||
this.root = root;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets hooks.
|
||||
*
|
||||
* @return the hooks
|
||||
* @throws IOException
|
||||
* the io exception
|
||||
*/
|
||||
public List<GHHook> getHooks() throws IOException {
|
||||
|
||||
GHHook[] hookArray = root.createRequest().withUrlPath(collection()).fetch(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);
|
||||
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.createRequest().withUrlPath(collection() + "/" + id).fetch(clazz());
|
||||
return wrap(hook);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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());
|
||||
}
|
||||
|
||||
GHHook hook = root.createRequest()
|
||||
.method("POST")
|
||||
.with("name", name)
|
||||
.with("active", active)
|
||||
.with("config", config)
|
||||
.with("events", ea)
|
||||
.withUrlPath(collection())
|
||||
.fetch(clazz());
|
||||
|
||||
return wrap(hook);
|
||||
}
|
||||
|
||||
abstract String collection();
|
||||
|
||||
abstract Class<? extends GHHook[]> collectionClass();
|
||||
|
||||
abstract Class<? extends GHHook> clazz();
|
||||
|
||||
abstract GHHook wrap(GHHook hook);
|
||||
}
|
||||
|
||||
private static class RepoContext extends Context {
|
||||
private final GHRepository repository;
|
||||
private final GHUser owner;
|
||||
|
||||
private RepoContext(GHRepository repository, GHUser owner) {
|
||||
super(repository.root);
|
||||
this.repository = repository;
|
||||
this.owner = owner;
|
||||
}
|
||||
|
||||
@Override
|
||||
String collection() {
|
||||
return String.format("/repos/%s/%s/hooks", owner.getLogin(), repository.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
Class<? extends GHHook[]> collectionClass() {
|
||||
return GHRepoHook[].class;
|
||||
}
|
||||
|
||||
@Override
|
||||
Class<? extends GHHook> clazz() {
|
||||
return GHRepoHook.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
GHHook wrap(GHHook hook) {
|
||||
return ((GHRepoHook) hook).wrap(repository);
|
||||
}
|
||||
}
|
||||
|
||||
private static class OrgContext extends Context {
|
||||
private final GHOrganization organization;
|
||||
|
||||
private OrgContext(GHOrganization organization) {
|
||||
super(organization.root);
|
||||
this.organization = organization;
|
||||
}
|
||||
|
||||
@Override
|
||||
String collection() {
|
||||
return String.format("/orgs/%s/hooks", organization.getLogin());
|
||||
}
|
||||
|
||||
@Override
|
||||
Class<? extends GHHook[]> collectionClass() {
|
||||
return GHOrgHook[].class;
|
||||
}
|
||||
|
||||
@Override
|
||||
Class<? extends GHHook> clazz() {
|
||||
return GHOrgHook.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
GHHook wrap(GHHook hook) {
|
||||
return ((GHOrgHook) hook).wrap(organization);
|
||||
}
|
||||
}
|
||||
|
||||
static Context repoContext(GHRepository repository, GHUser owner) {
|
||||
return new RepoContext(repository, owner);
|
||||
}
|
||||
|
||||
static Context orgContext(GHOrganization organization) {
|
||||
return new OrgContext(organization);
|
||||
}
|
||||
}
|
||||
62
src/main/java/org/kohsuke/github/GHIOException.java
Normal file
62
src/main/java/org/kohsuke/github/GHIOException.java
Normal file
@@ -0,0 +1,62 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.annotation.CheckForNull;
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a {@code GHIOException} with the specified detail message and cause.
|
||||
*
|
||||
* @param message
|
||||
* The detail message (which is saved for later retrieval by the {@link #getMessage()} method)
|
||||
*
|
||||
* @param cause
|
||||
* The cause (which is saved for later retrieval by the {@link #getCause()} method). (A null value is
|
||||
* permitted, and indicates that the cause is nonexistent or unknown.)
|
||||
*/
|
||||
public GHIOException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets response header fields.
|
||||
*
|
||||
* @return the response header fields
|
||||
*/
|
||||
@CheckForNull
|
||||
public Map<String, List<String>> getResponseHeaderFields() {
|
||||
return responseHeaderFields;
|
||||
}
|
||||
|
||||
GHIOException withResponseHeaderFields(@Nonnull Map<String, List<String>> headerFields) {
|
||||
this.responseHeaderFields = headerFields;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
56
src/main/java/org/kohsuke/github/GHInvitation.java
Normal file
56
src/main/java/org/kohsuke/github/GHInvitation.java
Normal 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.createRequest().method("PATCH").withUrlPath("/user/repository_invitations/" + id).send();
|
||||
}
|
||||
|
||||
/**
|
||||
* Decline a repository invitation.
|
||||
*
|
||||
* @throws IOException
|
||||
* the io exception
|
||||
*/
|
||||
public void decline() throws IOException {
|
||||
root.createRequest().method("DELETE").withUrlPath("/user/repository_invitations/" + id).send();
|
||||
}
|
||||
|
||||
@Override
|
||||
public URL getHtmlUrl() {
|
||||
return GitHubClient.parseURL(html_url);
|
||||
}
|
||||
}
|
||||
@@ -24,76 +24,79 @@
|
||||
|
||||
package org.kohsuke.github;
|
||||
|
||||
import com.infradna.tool.bridge_method_injector.WithBridgeMethods;
|
||||
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
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 java.util.Locale;
|
||||
import java.util.Objects;
|
||||
|
||||
import static org.kohsuke.github.Previews.SQUIRREL_GIRL;
|
||||
|
||||
/**
|
||||
* Represents an issue on GitHub.
|
||||
*
|
||||
* @author Eric Maupin
|
||||
* @author Kohsuke Kawaguchi
|
||||
* @see GHRepository#getIssue(int) GHRepository#getIssue(int)
|
||||
* @see GitHub#searchIssues() GitHub#searchIssues()
|
||||
* @see GHIssueSearchBuilder
|
||||
*/
|
||||
public class GHIssue {
|
||||
public class GHIssue extends GHObject implements Reactable {
|
||||
private static final String ASSIGNEES = "assignees";
|
||||
|
||||
GitHub root;
|
||||
GHRepository owner;
|
||||
|
||||
// API v3
|
||||
protected GHUser assignee;
|
||||
|
||||
// API v3
|
||||
protected GHUser assignee; // not sure what this field is now that 'assignees' exist
|
||||
protected GHUser[] assignees;
|
||||
protected String state;
|
||||
protected int number;
|
||||
protected String closed_at;
|
||||
protected int comments;
|
||||
@SkipFromToString
|
||||
protected String body;
|
||||
protected List<Label> labels;
|
||||
protected List<GHLabel> labels;
|
||||
protected GHUser user;
|
||||
protected String title, created_at, html_url;
|
||||
protected String title, html_url;
|
||||
protected GHIssue.PullRequest pull_request;
|
||||
protected GHMilestone milestone;
|
||||
protected String url, updated_at;
|
||||
protected int id;
|
||||
protected GHUser closed_by;
|
||||
protected boolean locked;
|
||||
|
||||
public static class Label {
|
||||
private String url;
|
||||
private String name;
|
||||
private String color;
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getColor() {
|
||||
return color;
|
||||
}
|
||||
}
|
||||
|
||||
/*package*/ GHIssue wrap(GHRepository owner) {
|
||||
GHIssue wrap(GHRepository owner) {
|
||||
this.owner = owner;
|
||||
this.root = owner.root;
|
||||
if(milestone != null) milestone.wrap(owner);
|
||||
if(assignee != null) assignee.wrapUp(root);
|
||||
if(user != null) user.wrapUp(root);
|
||||
if(closed_by != null) closed_by.wrapUp(root);
|
||||
return this;
|
||||
if (milestone != null)
|
||||
milestone.wrap(owner);
|
||||
return wrap(owner.root);
|
||||
}
|
||||
|
||||
/*package*/ static GHIssue[] wrap(GHIssue[] issues, GHRepository owner) {
|
||||
for (GHIssue i : issues)
|
||||
i.wrap(owner);
|
||||
return issues;
|
||||
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);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Repository to which the issue belongs.
|
||||
*
|
||||
* @return the repository
|
||||
*/
|
||||
public GHRepository getRepository() {
|
||||
return owner;
|
||||
@@ -101,6 +104,8 @@ public class GHIssue {
|
||||
|
||||
/**
|
||||
* The description of this pull request.
|
||||
*
|
||||
* @return the body
|
||||
*/
|
||||
public String getBody() {
|
||||
return body;
|
||||
@@ -108,63 +113,140 @@ public class GHIssue {
|
||||
|
||||
/**
|
||||
* 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 getUrl() {
|
||||
return GitHub.parseURL(html_url);
|
||||
public URL getHtmlUrl() {
|
||||
return GitHubClient.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));
|
||||
}
|
||||
|
||||
public Collection<Label> getLabels() {
|
||||
if(labels == null){
|
||||
return Collections.EMPTY_LIST;
|
||||
/**
|
||||
* Gets labels.
|
||||
*
|
||||
* @return the labels
|
||||
* @throws IOException
|
||||
* the io exception
|
||||
*/
|
||||
public Collection<GHLabel> getLabels() throws IOException {
|
||||
if (labels == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return Collections.unmodifiableList(labels);
|
||||
}
|
||||
|
||||
public Date getCreatedAt() {
|
||||
return GitHub.parseDate(created_at);
|
||||
}
|
||||
|
||||
public Date getUpdatedAt() {
|
||||
return GitHub.parseDate(updated_at);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets closed at.
|
||||
*
|
||||
* @return the closed at
|
||||
*/
|
||||
public Date getClosedAt() {
|
||||
return GitHub.parseDate(closed_at);
|
||||
return GitHubClient.parseDate(closed_at);
|
||||
}
|
||||
|
||||
public URL getApiURL(){
|
||||
return GitHub.parseURL(url);
|
||||
}
|
||||
/**
|
||||
* Gets api url.
|
||||
*
|
||||
* @return API URL of this object.
|
||||
* @deprecated use {@link #getUrl()}
|
||||
*/
|
||||
@Deprecated
|
||||
public URL getApiURL() {
|
||||
return getUrl();
|
||||
}
|
||||
|
||||
/**
|
||||
* Lock.
|
||||
*
|
||||
* @throws IOException
|
||||
* the io exception
|
||||
*/
|
||||
public void lock() throws IOException {
|
||||
root.createRequest().method("PUT").withUrlPath(getApiRoute() + "/lock").send();
|
||||
}
|
||||
|
||||
/**
|
||||
* Unlock.
|
||||
*
|
||||
* @throws IOException
|
||||
* the io exception
|
||||
*/
|
||||
public void unlock() throws IOException {
|
||||
root.createRequest().method("PUT").withUrlPath(getApiRoute() + "/lock").send();
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the issue by adding a comment.
|
||||
*
|
||||
* @param message
|
||||
* the message
|
||||
* @return Newly posted comment.
|
||||
* @throws IOException
|
||||
* the io exception
|
||||
*/
|
||||
public void comment(String message) throws IOException {
|
||||
new Requester(root).with("body",message).to(getIssuesApiRoute() + "/comments");
|
||||
@WithBridgeMethods(void.class)
|
||||
public GHIssueComment comment(String message) throws IOException {
|
||||
GHIssueComment r = root.createRequest()
|
||||
.method("POST")
|
||||
.with("body", message)
|
||||
.withUrlPath(getIssuesApiRoute() + "/comments")
|
||||
.fetch(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());
|
||||
root.createRequest().with(key, value).method("PATCH").withUrlPath(getApiRoute()).send();
|
||||
}
|
||||
|
||||
/**
|
||||
* Identical to edit(), but allows null for the value.
|
||||
*/
|
||||
private void editNullable(String key, Object value) throws IOException {
|
||||
root.createRequest().withNullable(key, value).method("PATCH").withUrlPath(getApiRoute()).send();
|
||||
}
|
||||
|
||||
private void editIssue(String key, Object value) throws IOException {
|
||||
root.createRequest().with(key, value).method("PATCH").withUrlPath(getIssuesApiRoute()).send();
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes this issue.
|
||||
*
|
||||
* @throws IOException
|
||||
* the io exception
|
||||
*/
|
||||
public void close() throws IOException {
|
||||
edit("state", "closed");
|
||||
@@ -172,104 +254,474 @@ public class GHIssue {
|
||||
|
||||
/**
|
||||
* 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 the milestone for this issue.
|
||||
*
|
||||
* @param milestone
|
||||
* The milestone to assign this issue to. Use null to remove the milestone for this issue.
|
||||
* @throws IOException
|
||||
* The io exception
|
||||
*/
|
||||
public void setMilestone(GHMilestone milestone) throws IOException {
|
||||
if (milestone == null) {
|
||||
editNullable("milestone", null);
|
||||
} else {
|
||||
edit("milestone", milestone.getNumber());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign to.
|
||||
*
|
||||
* @param user
|
||||
* the user
|
||||
* @throws IOException
|
||||
* the io exception
|
||||
*/
|
||||
public void assignTo(GHUser user) throws IOException {
|
||||
edit("assignee",user.getLogin());
|
||||
setAssignees(user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets labels.
|
||||
*
|
||||
* @param labels
|
||||
* the labels
|
||||
* @throws IOException
|
||||
* the io exception
|
||||
*/
|
||||
public void setLabels(String... labels) throws IOException {
|
||||
edit("assignee",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.
|
||||
*/
|
||||
public PagedIterable<GHIssueComment> listComments() throws IOException {
|
||||
return new PagedIterable<GHIssueComment>() {
|
||||
public PagedIterator<GHIssueComment> iterator() {
|
||||
return new PagedIterator<GHIssueComment>(root.retrieve().asIterator(getIssuesApiRoute() + "/comments", GHIssueComment[].class)) {
|
||||
protected void wrapUp(GHIssueComment[] page) {
|
||||
for (GHIssueComment c : page)
|
||||
c.wrapUp(GHIssue.this);
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
public List<GHIssueComment> getComments() throws IOException {
|
||||
return listComments().toList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtains all the comments associated with this issue.
|
||||
*
|
||||
* @return the paged iterable
|
||||
* @throws IOException
|
||||
* the io exception
|
||||
*/
|
||||
public PagedIterable<GHIssueComment> listComments() throws IOException {
|
||||
return root.createRequest()
|
||||
.withUrlPath(getIssuesApiRoute() + "/comments")
|
||||
.toIterable(GHIssueComment[].class, item -> item.wrapUp(this));
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Deprecated
|
||||
public GHReaction createReaction(ReactionContent content) throws IOException {
|
||||
return root.createRequest()
|
||||
.method("POST")
|
||||
.withPreview(SQUIRREL_GIRL)
|
||||
.with("content", content.getContent())
|
||||
.withUrlPath(getApiRoute() + "/reactions")
|
||||
.fetch(GHReaction.class)
|
||||
.wrap(root);
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Deprecated
|
||||
public PagedIterable<GHReaction> listReactions() {
|
||||
return root.createRequest()
|
||||
.withPreview(SQUIRREL_GIRL)
|
||||
.withUrlPath(getApiRoute() + "/reactions")
|
||||
.toIterable(GHReaction[].class, item -> item.wrap(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 {
|
||||
root.createRequest()
|
||||
.method("POST")
|
||||
.with(ASSIGNEES, getLogins(assignees))
|
||||
.withUrlPath(getIssuesApiRoute() + "/assignees")
|
||||
.fetchInto(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 {
|
||||
root.createRequest()
|
||||
.method("PATCH")
|
||||
.with(ASSIGNEES, getLogins(assignees))
|
||||
.withUrlPath(getIssuesApiRoute())
|
||||
.send();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 {
|
||||
root.createRequest()
|
||||
.method("DELETE")
|
||||
.with(ASSIGNEES, getLogins(assignees))
|
||||
.inBody()
|
||||
.withUrlPath(getIssuesApiRoute() + "/assignees")
|
||||
.fetchInto(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets api route.
|
||||
*
|
||||
* @return the api route
|
||||
*/
|
||||
protected String getApiRoute() {
|
||||
return getIssuesApiRoute();
|
||||
}
|
||||
|
||||
private String getIssuesApiRoute() {
|
||||
return "/repos/"+owner.getOwnerName()+"/"+owner.getName()+"/issues/"+number;
|
||||
/**
|
||||
* Gets issues api route.
|
||||
*
|
||||
* @return the issues api route
|
||||
*/
|
||||
protected String getIssuesApiRoute() {
|
||||
if (owner == null) {
|
||||
// Issues returned from search to do not have an owner. Attempt to use url.
|
||||
final URL url = Objects.requireNonNull(getUrl(), "Missing instance URL!");
|
||||
return StringUtils.prependIfMissing(url.toString().replace(root.getApiUrl(), ""), "/");
|
||||
}
|
||||
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));
|
||||
}
|
||||
|
||||
public GHUser getAssignee() {
|
||||
return assignee;
|
||||
}
|
||||
|
||||
/**
|
||||
* User who submitted the issue.
|
||||
*
|
||||
* @return the user
|
||||
* @throws IOException
|
||||
* the io exception
|
||||
*/
|
||||
public GHUser getUser() {
|
||||
return user;
|
||||
}
|
||||
|
||||
public GHUser getClosedBy() {
|
||||
if(!"closed".equals(state)) return null;
|
||||
if(closed_by != null) return closed_by;
|
||||
|
||||
//TODO closed_by = owner.getIssue(number).getClosed_by();
|
||||
return closed_by;
|
||||
}
|
||||
|
||||
public int getCommentsCount(){
|
||||
return comments;
|
||||
}
|
||||
public GHUser getUser() throws IOException {
|
||||
return root.intern(user);
|
||||
}
|
||||
|
||||
public PullRequest getPullRequest() {
|
||||
return pull_request;
|
||||
}
|
||||
/**
|
||||
* 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
|
||||
* 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;
|
||||
|
||||
public GHMilestone getMilestone() {
|
||||
return milestone;
|
||||
}
|
||||
// TODO
|
||||
/*
|
||||
* if (closed_by==null) { closed_by = owner.getIssue(number).getClosed_by(); }
|
||||
*/
|
||||
return root.intern(closed_by);
|
||||
}
|
||||
|
||||
public static class PullRequest{
|
||||
private String diff_url, patch_url, html_url;
|
||||
|
||||
public URL getDiffUrl() {
|
||||
return GitHub.parseURL(diff_url);
|
||||
}
|
||||
|
||||
public URL getPatchUrl() {
|
||||
return GitHub.parseURL(patch_url);
|
||||
}
|
||||
|
||||
public URL getUrl() {
|
||||
return GitHub.parseURL(html_url);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets milestone.
|
||||
*
|
||||
* @return the milestone
|
||||
*/
|
||||
public GHMilestone getMilestone() {
|
||||
return milestone;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 GitHubClient.parseURL(diff_url);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets patch url.
|
||||
*
|
||||
* @return the patch url
|
||||
*/
|
||||
public URL getPatchUrl() {
|
||||
return GitHubClient.parseURL(patch_url);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets url.
|
||||
*
|
||||
* @return the url
|
||||
*/
|
||||
public URL getUrl() {
|
||||
return GitHubClient.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.createRequest()
|
||||
.withUrlPath(owner.getApiTailUrl(String.format("/issues/%s/events", number)))
|
||||
.toIterable(GHIssueEvent[].class, item -> item.wrapUp(this));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,55 +5,98 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* The type GHIssueBuilder.
|
||||
*
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
public class GHIssueBuilder {
|
||||
private final GHRepository repo;
|
||||
private final Requester builder;
|
||||
private List<String> labels = new ArrayList<String>();
|
||||
private List<String> assignees = new ArrayList<String>();
|
||||
|
||||
GHIssueBuilder(GHRepository repo, String title) {
|
||||
this.repo = repo;
|
||||
this.builder = new Requester(repo.root);
|
||||
builder.with("title",title);
|
||||
this.builder = repo.root.createRequest().method("POST");
|
||||
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)
|
||||
builder.with("assignee",user.getLogin());
|
||||
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)
|
||||
builder.with("assignee",user);
|
||||
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).to(repo.getApiTailUrl("issues"),GHIssue.class).wrap(repo);
|
||||
return builder.with("labels", labels)
|
||||
.with("assignees", assignees)
|
||||
.withUrlPath(repo.getApiTailUrl("issues"))
|
||||
.fetch(GHIssue.class)
|
||||
.wrap(repo);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,28 +25,31 @@ package org.kohsuke.github;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.Date;
|
||||
|
||||
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 {
|
||||
public class GHIssueComment extends GHObject implements Reactable {
|
||||
GHIssue owner;
|
||||
|
||||
private String body, gravatar_id, created_at, updated_at;
|
||||
private URL url;
|
||||
private int id;
|
||||
private GHUser user;
|
||||
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;
|
||||
@@ -54,29 +57,17 @@ public class GHIssueComment {
|
||||
|
||||
/**
|
||||
* The comment itself.
|
||||
*
|
||||
* @return the body
|
||||
*/
|
||||
public String getBody() {
|
||||
return body;
|
||||
}
|
||||
|
||||
public Date getCreatedAt() {
|
||||
return GitHub.parseDate(created_at);
|
||||
}
|
||||
|
||||
public Date getUpdatedAt() {
|
||||
return GitHub.parseDate(updated_at);
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public URL getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the ID of the user who posted this comment.
|
||||
*
|
||||
* @return the user name
|
||||
*/
|
||||
@Deprecated
|
||||
public String getUserName() {
|
||||
@@ -85,8 +76,79 @@ public class GHIssueComment {
|
||||
|
||||
/**
|
||||
* 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());
|
||||
return owner == null || owner.root.isOffline() ? user : owner.root.getUser(user.getLogin());
|
||||
}
|
||||
|
||||
@Override
|
||||
public URL getHtmlUrl() {
|
||||
return GitHubClient.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 {
|
||||
owner.root.createRequest()
|
||||
.method("PATCH")
|
||||
.with("body", body)
|
||||
.withUrlPath(getApiRoute())
|
||||
.fetch(GHIssueComment.class);
|
||||
this.body = body;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes this issue comment.
|
||||
*
|
||||
* @throws IOException
|
||||
* the io exception
|
||||
*/
|
||||
public void delete() throws IOException {
|
||||
owner.root.createRequest().method("DELETE").withUrlPath(getApiRoute()).send();
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Deprecated
|
||||
public GHReaction createReaction(ReactionContent content) throws IOException {
|
||||
return owner.root.createRequest()
|
||||
.method("POST")
|
||||
.withPreview(SQUIRREL_GIRL)
|
||||
.with("content", content.getContent())
|
||||
.withUrlPath(getApiRoute() + "/reactions")
|
||||
.fetch(GHReaction.class)
|
||||
.wrap(owner.root);
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Deprecated
|
||||
public PagedIterable<GHReaction> listReactions() {
|
||||
return owner.root.createRequest()
|
||||
.withPreview(SQUIRREL_GIRL)
|
||||
.withUrlPath(getApiRoute() + "/reactions")
|
||||
.toIterable(GHReaction[].class, item -> item.wrap(owner.root));
|
||||
}
|
||||
|
||||
private String getApiRoute() {
|
||||
return "/repos/" + owner.getRepository().getOwnerName() + "/" + owner.getRepository().getName()
|
||||
+ "/issues/comments/" + getId();
|
||||
}
|
||||
}
|
||||
|
||||
168
src/main/java/org/kohsuke/github/GHIssueEvent.java
Normal file
168
src/main/java/org/kohsuke/github/GHIssueEvent.java
Normal file
@@ -0,0 +1,168 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* The type GHIssueEvent.
|
||||
*
|
||||
* @see <a href="https://developer.github.com/v3/issues/events/">Github documentation for issue events</a>
|
||||
*
|
||||
* @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 GHMilestone milestone;
|
||||
private GHLabel label;
|
||||
private GHUser assignee;
|
||||
|
||||
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 GitHubClient.parseDate(created_at);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets root.
|
||||
*
|
||||
* @return the root
|
||||
*/
|
||||
public GitHub getRoot() {
|
||||
return root;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets issue.
|
||||
*
|
||||
* @return the issue
|
||||
*/
|
||||
public GHIssue getIssue() {
|
||||
return issue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the {@link GHMilestone} that this issue was added to or removed from. Only present for events "milestoned"
|
||||
* and "demilestoned", <code>null</code> otherwise.
|
||||
*
|
||||
* @return the milestone
|
||||
*/
|
||||
public GHMilestone getMilestone() {
|
||||
return milestone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the {@link GHLabel} that was added to or removed from the issue. Only present for events "labeled" and
|
||||
* "unlabeled", <code>null</code> otherwise.
|
||||
*
|
||||
* @return the label
|
||||
*/
|
||||
public GHLabel getLabel() {
|
||||
return label;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the {@link GHUser} that was assigned or unassigned from the issue. Only present for events "assigned" and
|
||||
* "unassigned", <code>null</code> otherwise.
|
||||
*
|
||||
* @return the user
|
||||
*/
|
||||
public GHUser getAssignee() {
|
||||
return assignee;
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
}
|
||||
117
src/main/java/org/kohsuke/github/GHIssueSearchBuilder.java
Normal file
117
src/main/java/org/kohsuke/github/GHIssueSearchBuilder.java
Normal file
@@ -0,0 +1,117 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
/**
|
||||
* Search issues.
|
||||
*
|
||||
* @author Kohsuke Kawaguchi
|
||||
* @see GitHub#searchIssues() GitHub#searchIssues()
|
||||
*/
|
||||
public class GHIssueSearchBuilder extends GHSearchBuilder<GHIssue> {
|
||||
GHIssueSearchBuilder(GitHub root) {
|
||||
super(root, IssueSearchResult.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Search terms.
|
||||
*/
|
||||
public GHIssueSearchBuilder q(String term) {
|
||||
super.q(term);
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
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);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* The enum Sort.
|
||||
*/
|
||||
public enum Sort {
|
||||
COMMENTS, CREATED, UPDATED
|
||||
}
|
||||
|
||||
private static class IssueSearchResult extends SearchResult<GHIssue> {
|
||||
private GHIssue[] items;
|
||||
|
||||
@Override
|
||||
GHIssue[] getItems(GitHub root) {
|
||||
for (GHIssue i : items)
|
||||
i.wrap(root);
|
||||
return items;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getApiUrl() {
|
||||
return "/search/issues";
|
||||
}
|
||||
}
|
||||
@@ -24,7 +24,11 @@
|
||||
|
||||
package org.kohsuke.github;
|
||||
|
||||
/**
|
||||
* The enum GHIssueState.
|
||||
*
|
||||
* @see GHPullRequestQueryBuilder#state(GHIssueState) GHPullRequestQueryBuilder#state(GHIssueState)
|
||||
*/
|
||||
public enum GHIssueState {
|
||||
OPEN,
|
||||
CLOSED
|
||||
OPEN, CLOSED, ALL
|
||||
}
|
||||
@@ -1,48 +1,81 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
import org.apache.commons.lang.builder.ToStringBuilder;
|
||||
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
|
||||
/**
|
||||
* SSH public key.
|
||||
*
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
@SuppressFBWarnings(value = "UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", justification = "JSON API")
|
||||
public class GHKey {
|
||||
/*package almost final*/ GitHub root;
|
||||
/* package almost final */ GitHub root;
|
||||
|
||||
private String url, key, title;
|
||||
private boolean verified;
|
||||
private int id;
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
267
src/main/java/org/kohsuke/github/GHLabel.java
Normal file
267
src/main/java/org/kohsuke/github/GHLabel.java
Normal file
@@ -0,0 +1,267 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JacksonInject;
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import javax.annotation.CheckForNull;
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
/**
|
||||
* The type GHLabel.
|
||||
*
|
||||
* @author Kohsuke Kawaguchi
|
||||
* @see <a href="https://developer.github.com/v3/issues/labels/">Labels</a>
|
||||
* @see GHIssue#getLabels() GHIssue#getLabels()
|
||||
* @see GHRepository#listLabels() GHRepository#listLabels()
|
||||
*/
|
||||
public class GHLabel {
|
||||
|
||||
@Nonnull
|
||||
private String url, name, color;
|
||||
|
||||
@CheckForNull
|
||||
private String description;
|
||||
|
||||
@Nonnull
|
||||
private final GitHub root;
|
||||
|
||||
@JsonCreator
|
||||
private GHLabel(@JacksonInject @Nonnull GitHub root) {
|
||||
this.root = root;
|
||||
url = "";
|
||||
name = "";
|
||||
color = "";
|
||||
description = null;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
GitHub getApiRoot() {
|
||||
return Objects.requireNonNull(root);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets url.
|
||||
*
|
||||
* @return the url
|
||||
*/
|
||||
@Nonnull
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets name.
|
||||
*
|
||||
* @return the name
|
||||
*/
|
||||
@Nonnull
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Color code without leading '#', such as 'f29513'
|
||||
*
|
||||
* @return the color
|
||||
*/
|
||||
@Nonnull
|
||||
public String getColor() {
|
||||
return color;
|
||||
}
|
||||
|
||||
/**
|
||||
* Purpose of Label
|
||||
*
|
||||
* @return the description
|
||||
*/
|
||||
@CheckForNull
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets color.
|
||||
*
|
||||
* @param newColor
|
||||
* 6-letter hex color code, like "f29513"
|
||||
* @throws IOException
|
||||
* the io exception
|
||||
* @deprecated use {@link #set()} or {@link #update()} instead
|
||||
*/
|
||||
@Deprecated
|
||||
public void setColor(String newColor) throws IOException {
|
||||
set().color(newColor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets description.
|
||||
*
|
||||
* @param newDescription
|
||||
* Description of label
|
||||
* @throws IOException
|
||||
* the io exception
|
||||
* @deprecated use {@link #set()} or {@link #update()} instead
|
||||
*/
|
||||
@Deprecated
|
||||
public void setDescription(String newDescription) throws IOException {
|
||||
set().description(newDescription);
|
||||
}
|
||||
|
||||
static Collection<String> toNames(Collection<GHLabel> labels) {
|
||||
List<String> r = new ArrayList<>();
|
||||
for (GHLabel l : labels) {
|
||||
r.add(l.getName());
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* Begins the creation of a new instance.
|
||||
*
|
||||
* Consumer must call {@link Creator#done()} to commit changes.
|
||||
*
|
||||
* @param repository
|
||||
* the repository in which the label will be created.
|
||||
* @return a {@link Creator}
|
||||
* @throws IOException
|
||||
* the io exception
|
||||
*/
|
||||
@Preview
|
||||
@Deprecated
|
||||
static Creator create(GHRepository repository) throws IOException {
|
||||
return new Creator(repository);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a label from a repository.
|
||||
*
|
||||
* @param repository
|
||||
* the repository to read from
|
||||
* @param name
|
||||
* the name of the label
|
||||
* @return a label
|
||||
* @throws IOException
|
||||
* the io exception
|
||||
*/
|
||||
static GHLabel read(@Nonnull GHRepository repository, @Nonnull String name) throws IOException {
|
||||
return repository.root.createRequest()
|
||||
.withUrlPath(repository.getApiTailUrl("labels"), name)
|
||||
.fetch(GHLabel.class);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads all labels from a repository.
|
||||
*
|
||||
* @param repository
|
||||
* the repository to read from
|
||||
* @return iterable of all labels
|
||||
* @throws IOException
|
||||
* the io exception
|
||||
*/
|
||||
static PagedIterable<GHLabel> readAll(@Nonnull final GHRepository repository) throws IOException {
|
||||
return repository.root.createRequest()
|
||||
.withUrlPath(repository.getApiTailUrl("labels"))
|
||||
.toIterable(GHLabel[].class, null);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Begins a batch update
|
||||
*
|
||||
* Consumer must call {@link Updater#done()} to commit changes.
|
||||
*
|
||||
* @return a {@link Updater}
|
||||
*/
|
||||
@Preview
|
||||
@Deprecated
|
||||
public Updater update() {
|
||||
return new Updater(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Begins a single property update.
|
||||
*
|
||||
* @return a {@link Setter}
|
||||
*/
|
||||
@Preview
|
||||
@Deprecated
|
||||
public Setter set() {
|
||||
return new Setter(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete this label from the repository.
|
||||
*
|
||||
* @throws IOException
|
||||
* the io exception
|
||||
*/
|
||||
public void delete() throws IOException {
|
||||
root.createRequest().method("DELETE").setRawUrlPath(getUrl()).send();
|
||||
}
|
||||
|
||||
@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(description, ghLabel.description);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(url, name, color, description);
|
||||
}
|
||||
|
||||
/**
|
||||
* A {@link GHLabelBuilder} that updates a single property per request
|
||||
*
|
||||
* {@link #done()} is called automatically after the property is set.
|
||||
*/
|
||||
@Preview
|
||||
@Deprecated
|
||||
public static class Setter extends GHLabelBuilder<GHLabel> {
|
||||
private Setter(@Nonnull GHLabel base) {
|
||||
super(GHLabel.class, base.getApiRoot(), base);
|
||||
requester.method("PATCH").setRawUrlPath(base.getUrl());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A {@link GHLabelBuilder} that allows multiple properties to be updated per request.
|
||||
*
|
||||
* Consumer must call {@link #done()} to commit changes.
|
||||
*/
|
||||
@Preview
|
||||
@Deprecated
|
||||
public static class Updater extends GHLabelBuilder<Updater> {
|
||||
private Updater(@Nonnull GHLabel base) {
|
||||
super(Updater.class, base.getApiRoot(), base);
|
||||
requester.method("PATCH").setRawUrlPath(base.getUrl());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A {@link GHLabelBuilder} that creates a new {@link GHLabel}
|
||||
*
|
||||
* Consumer must call {@link #done()} to create the new instance.
|
||||
*/
|
||||
@Preview
|
||||
@Deprecated
|
||||
public static class Creator extends GHLabelBuilder<Creator> {
|
||||
private Creator(@Nonnull GHRepository repository) {
|
||||
super(Creator.class, repository.root, null);
|
||||
requester.method("POST").withUrlPath(repository.getApiTailUrl("labels"));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
60
src/main/java/org/kohsuke/github/GHLabelBuilder.java
Normal file
60
src/main/java/org/kohsuke/github/GHLabelBuilder.java
Normal file
@@ -0,0 +1,60 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.annotation.CheckForNull;
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param <S>
|
||||
* Intermediate return type for this builder returned by calls to {@link #with(String, Object)}. If {@link S}
|
||||
* the same as {@link GHLabel}, this builder will commit changes after each call to
|
||||
* {@link #with(String, Object)}.
|
||||
*/
|
||||
class GHLabelBuilder<S> extends AbstractBuilder<GHLabel, S> {
|
||||
|
||||
/**
|
||||
*
|
||||
* @param intermediateReturnType
|
||||
* Intermediate return type for this builder returned by calls to {@link #with(String, Object)}. If
|
||||
* {@link S} the same as {@link GHLabel}, this builder will commit changes after each call to
|
||||
* {@link #with(String, Object)}.
|
||||
* @param root
|
||||
* the GitHub instance to which updates will be sent
|
||||
* @param baseInstance
|
||||
* instance on which to base this builder. If {@code null} a new instance will be created.
|
||||
*/
|
||||
protected GHLabelBuilder(@Nonnull Class<S> intermediateReturnType,
|
||||
@Nonnull GitHub root,
|
||||
@CheckForNull GHLabel baseInstance) {
|
||||
super(GHLabel.class, intermediateReturnType, root, baseInstance);
|
||||
|
||||
if (baseInstance != null) {
|
||||
requester.with("name", baseInstance.getName());
|
||||
requester.with("color", baseInstance.getColor());
|
||||
requester.with("description", baseInstance.getDescription());
|
||||
}
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Preview
|
||||
@Deprecated
|
||||
public S name(String value) throws IOException {
|
||||
return with("name", value);
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Preview
|
||||
@Deprecated
|
||||
public S color(String value) throws IOException {
|
||||
return with("color", value);
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Preview
|
||||
@Deprecated
|
||||
public S description(String value) throws IOException {
|
||||
return with("description", value);
|
||||
}
|
||||
}
|
||||
224
src/main/java/org/kohsuke/github/GHLicense.java
Normal file
224
src/main/java/org/kohsuke/github/GHLicense.java
Normal file
@@ -0,0 +1,224 @@
|
||||
/*
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright (c) 2016, Duncan Dickinson
|
||||
*
|
||||
* 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 edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* The GitHub Preview API's license information
|
||||
*
|
||||
* @author Duncan Dickinson
|
||||
* @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>
|
||||
*/
|
||||
@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;
|
||||
|
||||
// these fields are always present, even in the short form
|
||||
protected String key, name;
|
||||
|
||||
// the rest is only after populated
|
||||
protected Boolean featured;
|
||||
|
||||
protected String html_url, description, category, implementation, body;
|
||||
|
||||
protected List<String> required = new ArrayList<String>();
|
||||
protected List<String> permitted = new ArrayList<String>();
|
||||
protected List<String> forbidden = new ArrayList<String>();
|
||||
|
||||
/**
|
||||
* Gets key.
|
||||
*
|
||||
* @return a mnemonic for the license
|
||||
*/
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets name.
|
||||
*
|
||||
* @return the license name
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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();
|
||||
return featured;
|
||||
}
|
||||
|
||||
public URL getHtmlUrl() throws IOException {
|
||||
populate();
|
||||
return GitHubClient.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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 (root == null || root.isOffline()) {
|
||||
return; // cannot populate, will have to live with what we have
|
||||
}
|
||||
|
||||
URL url = getUrl();
|
||||
if (url != null) {
|
||||
root.createRequest().setRawUrlPath(url.toString()).fetchInto(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o)
|
||||
return true;
|
||||
if (!(o instanceof GHLicense))
|
||||
return false;
|
||||
|
||||
GHLicense that = (GHLicense) o;
|
||||
return Objects.equals(getUrl(), that.getUrl());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(getUrl());
|
||||
}
|
||||
|
||||
GHLicense wrap(GitHub root) {
|
||||
this.root = root;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
88
src/main/java/org/kohsuke/github/GHMarketplaceAccount.java
Normal file
88
src/main/java/org/kohsuke/github/GHMarketplaceAccount.java
Normal file
@@ -0,0 +1,88 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
import java.net.URL;
|
||||
|
||||
/**
|
||||
* Base class for Github Marketplace Account.
|
||||
*
|
||||
* @author Paulo Miguel Almeida
|
||||
* @see GitHub#getMyMarketplacePurchases()
|
||||
* @see GHMarketplaceListAccountBuilder#createRequest()
|
||||
*/
|
||||
public class GHMarketplaceAccount {
|
||||
|
||||
protected GitHub root;
|
||||
private String url;
|
||||
private long id;
|
||||
private String login;
|
||||
private String email;
|
||||
private String organizationBillingEmail;
|
||||
private GHMarketplaceAccountType type;
|
||||
|
||||
/**
|
||||
* Wrap up gh marketplace account.
|
||||
*
|
||||
* @param root
|
||||
* the root
|
||||
* @return an instance of the GHMarketplaceAccount class
|
||||
*/
|
||||
GHMarketplaceAccount wrapUp(GitHub root) {
|
||||
this.root = root;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets url.
|
||||
*
|
||||
* @return the url
|
||||
*/
|
||||
public URL getUrl() {
|
||||
return GitHubClient.parseURL(url);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets id.
|
||||
*
|
||||
* @return the id
|
||||
*/
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets login.
|
||||
*
|
||||
* @return the login
|
||||
*/
|
||||
public String getLogin() {
|
||||
return login;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets email.
|
||||
*
|
||||
* @return the email
|
||||
*/
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets organization billing email.
|
||||
*
|
||||
* @return the organization billing email
|
||||
*/
|
||||
public String getOrganizationBillingEmail() {
|
||||
return organizationBillingEmail;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets type.
|
||||
*
|
||||
* @return the type
|
||||
*/
|
||||
public GHMarketplaceAccountType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||
|
||||
/**
|
||||
* A Github Marketplace Account Plan.
|
||||
*
|
||||
* @author Paulo Miguel Almeida
|
||||
* @see GHMarketplaceListAccountBuilder#createRequest()
|
||||
*/
|
||||
public class GHMarketplaceAccountPlan extends GHMarketplaceAccount {
|
||||
|
||||
@SuppressFBWarnings(value = "UWF_UNWRITTEN_FIELD", justification = "Field comes from JSON deserialization")
|
||||
private GHMarketplacePendingChange marketplacePendingChange;
|
||||
@SuppressFBWarnings(value = "UWF_UNWRITTEN_FIELD", justification = "Field comes from JSON deserialization")
|
||||
private GHMarketplacePurchase marketplacePurchase;
|
||||
|
||||
/**
|
||||
* Wrap up gh marketplace account.
|
||||
*
|
||||
* @param root
|
||||
* the root
|
||||
* @return an instance of the GHMarketplaceAccount class
|
||||
*/
|
||||
GHMarketplaceAccountPlan wrapUp(GitHub root) {
|
||||
super.wrapUp(root);
|
||||
if (this.marketplacePendingChange != null)
|
||||
this.marketplacePendingChange.wrapUp(this.root);
|
||||
|
||||
if (this.marketplacePurchase != null)
|
||||
this.marketplacePurchase.wrapUp(this.root);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets marketplace pending change.
|
||||
*
|
||||
* @return the marketplace pending change
|
||||
*/
|
||||
public GHMarketplacePendingChange getMarketplacePendingChange() {
|
||||
return marketplacePendingChange;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets marketplace purchase.
|
||||
*
|
||||
* @return the marketplace purchase
|
||||
*/
|
||||
public GHMarketplacePurchase getMarketplacePurchase() {
|
||||
return marketplacePurchase;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* GitHub Marketplace Account type.
|
||||
*
|
||||
* @author Paulo Miguel Almeida
|
||||
* @see GHMarketplaceAccount
|
||||
*/
|
||||
public enum GHMarketplaceAccountType {
|
||||
ORGANIZATION, USER;
|
||||
|
||||
/**
|
||||
* Returns GitHub's internal representation of this event.
|
||||
*/
|
||||
String symbol() {
|
||||
return StringUtils.capitalize(name().toLowerCase(Locale.ENGLISH));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Returns any accounts associated with a plan, including free plans
|
||||
*
|
||||
* @author Paulo Miguel Almeida
|
||||
* @see GHMarketplacePlan#listAccounts()
|
||||
*/
|
||||
public class GHMarketplaceListAccountBuilder {
|
||||
private final GitHub root;
|
||||
private final Requester builder;
|
||||
private final long planId;
|
||||
|
||||
GHMarketplaceListAccountBuilder(GitHub root, long planId) {
|
||||
this.root = root;
|
||||
this.builder = root.createRequest();
|
||||
this.planId = planId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the GitHub accounts by the date they were created or last updated. Can be one of created or updated.
|
||||
* <p>
|
||||
* If omitted, the default sorting strategy will be "CREATED"
|
||||
*
|
||||
* @param sort
|
||||
* the sort strategy
|
||||
* @return a GHMarketplaceListAccountBuilder
|
||||
*/
|
||||
public GHMarketplaceListAccountBuilder sort(Sort sort) {
|
||||
this.builder.with("sort", sort);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Orders the GitHub accounts results, Can be one of asc or desc. Ignored without the sort parameter.
|
||||
*
|
||||
* @param direction
|
||||
* the order strategy
|
||||
* @return a GHMarketplaceListAccountBuilder
|
||||
*/
|
||||
public GHMarketplaceListAccountBuilder direction(GHDirection direction) {
|
||||
this.builder.with("direction", direction);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* The enum Sort.
|
||||
*/
|
||||
public enum Sort {
|
||||
CREATED, UPDATED
|
||||
}
|
||||
|
||||
/**
|
||||
* List any accounts associated with the plan specified on construction with all the order/sort parameters set.
|
||||
* <p>
|
||||
* GitHub Apps must use a JWT to access this endpoint.
|
||||
* <p>
|
||||
* OAuth Apps must use basic authentication with their client ID and client secret to access this endpoint.
|
||||
*
|
||||
* @return a paged iterable instance of GHMarketplaceAccountPlan
|
||||
* @throws IOException
|
||||
* on error
|
||||
*/
|
||||
public PagedIterable<GHMarketplaceAccountPlan> createRequest() throws IOException {
|
||||
return builder.withUrlPath(String.format("/marketplace_listing/plans/%d/accounts", this.planId))
|
||||
.toIterable(GHMarketplaceAccountPlan[].class, item -> item.wrapUp(root));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* A Github Marketplace purchase pending change.
|
||||
*
|
||||
* @author Paulo Miguel Almeida
|
||||
* @see GHMarketplaceListAccountBuilder#createRequest()
|
||||
*/
|
||||
public class GHMarketplacePendingChange {
|
||||
private GitHub root;
|
||||
private long id;
|
||||
@SuppressFBWarnings(value = "UWF_UNWRITTEN_FIELD", justification = "Field comes from JSON deserialization")
|
||||
private Long unitCount;
|
||||
@SuppressFBWarnings(value = "UWF_UNWRITTEN_FIELD", justification = "Field comes from JSON deserialization")
|
||||
private GHMarketplacePlan plan;
|
||||
@SuppressFBWarnings(value = "UWF_UNWRITTEN_FIELD", justification = "Field comes from JSON deserialization")
|
||||
private String effectiveDate;
|
||||
|
||||
/**
|
||||
* Wrap up gh marketplace pending change.
|
||||
*
|
||||
* @param root
|
||||
* the root
|
||||
* @return an instance of the GHMarketplacePendingChange class
|
||||
*/
|
||||
GHMarketplacePendingChange wrapUp(GitHub root) {
|
||||
this.root = root;
|
||||
if (plan != null) { // sanity check
|
||||
this.plan.wrapUp(this.root);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets id.
|
||||
*
|
||||
* @return the id
|
||||
*/
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets unit count.
|
||||
*
|
||||
* @return the unit count
|
||||
*/
|
||||
public Long getUnitCount() {
|
||||
return unitCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets plan.
|
||||
*
|
||||
* @return the plan
|
||||
*/
|
||||
public GHMarketplacePlan getPlan() {
|
||||
return plan;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets effective date.
|
||||
*
|
||||
* @return the effective date
|
||||
*/
|
||||
public Date getEffectiveDate() {
|
||||
return GitHubClient.parseDate(effectiveDate);
|
||||
}
|
||||
|
||||
}
|
||||
184
src/main/java/org/kohsuke/github/GHMarketplacePlan.java
Normal file
184
src/main/java/org/kohsuke/github/GHMarketplacePlan.java
Normal file
@@ -0,0 +1,184 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A Github Marketplace plan.
|
||||
*
|
||||
* @author Paulo Miguel Almeida
|
||||
* @see GitHub#listMarketplacePlans()
|
||||
*/
|
||||
public class GHMarketplacePlan {
|
||||
|
||||
private GitHub root;
|
||||
private String url;
|
||||
private String accountsUrl;
|
||||
private long id;
|
||||
private long number;
|
||||
private String name;
|
||||
private String description;
|
||||
private long monthlyPriceInCents;
|
||||
private long yearlyPriceInCents;
|
||||
private GHMarketplacePriceModel priceModel;
|
||||
@JsonProperty("has_free_trial")
|
||||
private boolean freeTrial; // JavaBeans Spec 1.01 section 8.3.2 forces us to have is<propertyName>
|
||||
private String unitName;
|
||||
private String state;
|
||||
private List<String> bullets;
|
||||
|
||||
/**
|
||||
* Wrap up gh marketplace plan.
|
||||
*
|
||||
* @param root
|
||||
* the root
|
||||
* @return an instance of the GHMarketplacePlan class
|
||||
*/
|
||||
GHMarketplacePlan wrapUp(GitHub root) {
|
||||
this.root = root;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets url.
|
||||
*
|
||||
* @return the url
|
||||
*/
|
||||
public URL getUrl() {
|
||||
return GitHubClient.parseURL(url);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets accounts url.
|
||||
*
|
||||
* @return the accounts url
|
||||
*/
|
||||
public String getAccountsUrl() {
|
||||
return accountsUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets id.
|
||||
*
|
||||
* @return the id
|
||||
*/
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets number.
|
||||
*
|
||||
* @return the number
|
||||
*/
|
||||
public long getNumber() {
|
||||
return number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets name.
|
||||
*
|
||||
* @return the name
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets description.
|
||||
*
|
||||
* @return the description
|
||||
*/
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets monthly price in cents.
|
||||
*
|
||||
* @return the monthly price in cents
|
||||
*/
|
||||
public long getMonthlyPriceInCents() {
|
||||
return monthlyPriceInCents;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets yearly price in cents.
|
||||
*
|
||||
* @return the yearly price in cents
|
||||
*/
|
||||
public long getYearlyPriceInCents() {
|
||||
return yearlyPriceInCents;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets price model.
|
||||
*
|
||||
* @return the price model
|
||||
*/
|
||||
public GHMarketplacePriceModel getPriceModel() {
|
||||
return priceModel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is free trial boolean.
|
||||
*
|
||||
* @return the boolean
|
||||
*/
|
||||
public boolean isFreeTrial() {
|
||||
return freeTrial;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets unit name.
|
||||
*
|
||||
* @return the unit name
|
||||
*/
|
||||
public String getUnitName() {
|
||||
return unitName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets state.
|
||||
*
|
||||
* @return the state
|
||||
*/
|
||||
public String getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets bullets.
|
||||
*
|
||||
* @return the bullets
|
||||
*/
|
||||
public List<String> getBullets() {
|
||||
return bullets;
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts a builder that list any accounts associated with a plan, including free plans. For per-seat pricing, you
|
||||
* see the list of accounts that have purchased the plan, including the number of seats purchased. When someone
|
||||
* submits a plan change that won't be processed until the end of their billing cycle, you will also see the
|
||||
* upcoming pending change.
|
||||
*
|
||||
* <p>
|
||||
* You use the returned builder to set various properties, then call
|
||||
* {@link GHMarketplaceListAccountBuilder#createRequest()} to finally list the accounts related to this plan.
|
||||
*
|
||||
* <p>
|
||||
* GitHub Apps must use a JWT to access this endpoint.
|
||||
* <p>
|
||||
* OAuth Apps must use basic authentication with their client ID and client secret to access this endpoint.
|
||||
*
|
||||
* @return a GHMarketplaceListAccountBuilder instance
|
||||
* @see <a href=
|
||||
* "https://developer.github.com/v3/apps/marketplace/#list-all-github-accounts-user-or-organization-on-a-specific-plan">List
|
||||
* all GitHub accounts (user or organization) on a specific plan</a>
|
||||
*/
|
||||
public GHMarketplaceListAccountBuilder listAccounts() {
|
||||
return new GHMarketplaceListAccountBuilder(root, this.id);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonValue;
|
||||
|
||||
/**
|
||||
* GitHub Marketplace plan pricing model.
|
||||
*
|
||||
* @author Paulo Miguel Almeida
|
||||
* @see GHMarketplacePlan
|
||||
*/
|
||||
public enum GHMarketplacePriceModel {
|
||||
FREE("free"), PER_UNIT("per-unit"), FLAT_RATE("flat-rate");
|
||||
|
||||
@JsonValue
|
||||
private final String internalName;
|
||||
|
||||
GHMarketplacePriceModel(String internalName) {
|
||||
this.internalName = internalName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns GitHub's internal representation of this event.
|
||||
*
|
||||
* @return a string containing GitHub's internal representation of this event.
|
||||
*/
|
||||
public String symbol() {
|
||||
return internalName;
|
||||
}
|
||||
}
|
||||
102
src/main/java/org/kohsuke/github/GHMarketplacePurchase.java
Normal file
102
src/main/java/org/kohsuke/github/GHMarketplacePurchase.java
Normal file
@@ -0,0 +1,102 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* A Github Marketplace purchase.
|
||||
*
|
||||
* @author Paulo Miguel Almeida
|
||||
* @see GHMarketplaceListAccountBuilder#createRequest() GHMarketplaceListAccountBuilder#createRequest()
|
||||
*/
|
||||
public class GHMarketplacePurchase {
|
||||
|
||||
private GitHub root;
|
||||
private String billingCycle;
|
||||
private String nextBillingDate;
|
||||
private boolean onFreeTrial;
|
||||
private String freeTrialEndsOn;
|
||||
private Long unitCount;
|
||||
private String updatedAt;
|
||||
@SuppressFBWarnings(value = "UWF_UNWRITTEN_FIELD", justification = "Field comes from JSON deserialization")
|
||||
private GHMarketplacePlan plan;
|
||||
|
||||
/**
|
||||
* Wrap up gh marketplace purchase.
|
||||
*
|
||||
* @param root
|
||||
* the root
|
||||
* @return an instance of the GHMarketplacePurchase class
|
||||
*/
|
||||
GHMarketplacePurchase wrapUp(GitHub root) {
|
||||
this.root = root;
|
||||
if (plan != null) { // sanity check
|
||||
this.plan.wrapUp(this.root);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets billing cycle.
|
||||
*
|
||||
* @return the billing cycle
|
||||
*/
|
||||
public String getBillingCycle() {
|
||||
return billingCycle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets next billing date.
|
||||
*
|
||||
* @return the next billing date
|
||||
*/
|
||||
public Date getNextBillingDate() {
|
||||
return GitHubClient.parseDate(nextBillingDate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Is on free trial boolean.
|
||||
*
|
||||
* @return the boolean
|
||||
*/
|
||||
public boolean isOnFreeTrial() {
|
||||
return onFreeTrial;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets free trial ends on.
|
||||
*
|
||||
* @return the free trial ends on
|
||||
*/
|
||||
public Date getFreeTrialEndsOn() {
|
||||
return GitHubClient.parseDate(freeTrialEndsOn);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets unit count.
|
||||
*
|
||||
* @return the unit count
|
||||
*/
|
||||
public Long getUnitCount() {
|
||||
return unitCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets updated at.
|
||||
*
|
||||
* @return the updated at
|
||||
*/
|
||||
public Date getUpdatedAt() {
|
||||
return GitHubClient.parseDate(updatedAt);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets plan.
|
||||
*
|
||||
* @return the plan
|
||||
*/
|
||||
public GHMarketplacePlan getPlan() {
|
||||
return plan;
|
||||
}
|
||||
}
|
||||
113
src/main/java/org/kohsuke/github/GHMarketplaceUserPurchase.java
Normal file
113
src/main/java/org/kohsuke/github/GHMarketplaceUserPurchase.java
Normal file
@@ -0,0 +1,113 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* Github Marketplace User Purchase
|
||||
*
|
||||
* @author Paulo Miguel Almeida
|
||||
* @see GitHub#getMyMarketplacePurchases()
|
||||
*/
|
||||
public class GHMarketplaceUserPurchase {
|
||||
protected GitHub root;
|
||||
private String billingCycle;
|
||||
private String nextBillingDate;
|
||||
private boolean onFreeTrial;
|
||||
private String freeTrialEndsOn;
|
||||
private Long unitCount;
|
||||
private String updatedAt;
|
||||
@SuppressFBWarnings(value = "UWF_UNWRITTEN_FIELD", justification = "Field comes from JSON deserialization")
|
||||
private GHMarketplaceAccount account;
|
||||
@SuppressFBWarnings(value = "UWF_UNWRITTEN_FIELD", justification = "Field comes from JSON deserialization")
|
||||
private GHMarketplacePlan plan;
|
||||
|
||||
/**
|
||||
* Wrap up GHMarketplaceUserPurchase.
|
||||
*
|
||||
* @param root
|
||||
* the root
|
||||
* @return an instance of the GHMarketplaceUserPurchase class
|
||||
*/
|
||||
GHMarketplaceUserPurchase wrapUp(GitHub root) {
|
||||
this.root = root;
|
||||
if (this.account != null)
|
||||
this.account.wrapUp(this.root);
|
||||
if (this.plan != null)
|
||||
this.plan.wrapUp(this.root);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets billing cycle.
|
||||
*
|
||||
* @return the billing cycle
|
||||
*/
|
||||
public String getBillingCycle() {
|
||||
return billingCycle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets next billing date.
|
||||
*
|
||||
* @return the next billing date
|
||||
*/
|
||||
public Date getNextBillingDate() {
|
||||
return GitHubClient.parseDate(nextBillingDate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Is on free trial boolean.
|
||||
*
|
||||
* @return the boolean
|
||||
*/
|
||||
public boolean isOnFreeTrial() {
|
||||
return onFreeTrial;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets free trial ends on.
|
||||
*
|
||||
* @return the free trial ends on
|
||||
*/
|
||||
public Date getFreeTrialEndsOn() {
|
||||
return GitHubClient.parseDate(freeTrialEndsOn);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets unit count.
|
||||
*
|
||||
* @return the unit count
|
||||
*/
|
||||
public Long getUnitCount() {
|
||||
return unitCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets updated at.
|
||||
*
|
||||
* @return the updated at
|
||||
*/
|
||||
public Date getUpdatedAt() {
|
||||
return GitHubClient.parseDate(updatedAt);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets account.
|
||||
*
|
||||
* @return the account
|
||||
*/
|
||||
public GHMarketplaceAccount getAccount() {
|
||||
return account;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets plan.
|
||||
*
|
||||
* @return the plan
|
||||
*/
|
||||
public GHMarketplacePlan getPlan() {
|
||||
return plan;
|
||||
}
|
||||
}
|
||||
107
src/main/java/org/kohsuke/github/GHMembership.java
Normal file
107
src/main/java/org/kohsuke/github/GHMembership.java
Normal file
@@ -0,0 +1,107 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* Represents a membership of a user in an organization.
|
||||
*
|
||||
* @author Kohsuke Kawaguchi
|
||||
* @see GHMyself#listOrgMemberships() GHMyself#listOrgMemberships()
|
||||
*/
|
||||
public class GHMembership /* extends GHObject --- but it doesn't have id, created_at, etc. */ {
|
||||
GitHub root;
|
||||
|
||||
String url;
|
||||
String state;
|
||||
String role;
|
||||
GHUser user;
|
||||
GHOrganization organization;
|
||||
|
||||
/**
|
||||
* Gets url.
|
||||
*
|
||||
* @return the url
|
||||
*/
|
||||
public URL getUrl() {
|
||||
return GitHubClient.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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accepts a pending invitation to an organization.
|
||||
*
|
||||
* @throws IOException
|
||||
* the io exception
|
||||
* @see GHMyself#getMembership(GHOrganization) GHMyself#getMembership(GHOrganization)
|
||||
*/
|
||||
public void activate() throws IOException {
|
||||
root.createRequest().method("PATCH").with("state", State.ACTIVE).withUrlPath(url).fetchInto(this);
|
||||
}
|
||||
|
||||
GHMembership wrap(GitHub root) {
|
||||
this.root = root;
|
||||
if (user != null)
|
||||
user = root.getUser(user.wrapUp(root));
|
||||
if (organization != null)
|
||||
organization.wrapUp(root);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Role of a user in an organization.
|
||||
*/
|
||||
public enum Role {
|
||||
/**
|
||||
* Organization owner.
|
||||
*/
|
||||
ADMIN,
|
||||
/**
|
||||
* Non-owner organization member.
|
||||
*/
|
||||
MEMBER;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether a role is currently active or waiting for acceptance (pending)
|
||||
*/
|
||||
public enum State {
|
||||
ACTIVE, PENDING;
|
||||
}
|
||||
}
|
||||
89
src/main/java/org/kohsuke/github/GHMeta.java
Normal file
89
src/main/java/org/kohsuke/github/GHMeta.java
Normal 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);
|
||||
}
|
||||
}
|
||||
@@ -1,73 +1,222 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Yusuke Kokubo
|
||||
* The type GHMilestone.
|
||||
*
|
||||
* @author Yusuke Kokubo
|
||||
*/
|
||||
public class GHMilestone {
|
||||
public class GHMilestone extends GHObject {
|
||||
GitHub root;
|
||||
GHRepository owner;
|
||||
GHRepository owner;
|
||||
|
||||
GHUser creator;
|
||||
private String state, due_on, title, url, created_at, description;
|
||||
private int closed_issues, open_issues, number;
|
||||
GHUser creator;
|
||||
private String state, due_on, title, description, html_url;
|
||||
private int closed_issues, open_issues, number;
|
||||
protected String closed_at;
|
||||
|
||||
public GitHub getRoot() {
|
||||
return root;
|
||||
}
|
||||
|
||||
public GHRepository getOwner() {
|
||||
return owner;
|
||||
}
|
||||
|
||||
public GHUser getCreator() {
|
||||
return creator;
|
||||
}
|
||||
|
||||
public Date getDueOn() {
|
||||
if (due_on == null) return null;
|
||||
return GitHub.parseDate(due_on);
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public Date getCreatedAt() {
|
||||
return GitHub.parseDate(created_at);
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public int getClosedIssues() {
|
||||
return closed_issues;
|
||||
}
|
||||
|
||||
public int getOpenIssues() {
|
||||
return open_issues;
|
||||
}
|
||||
|
||||
public int getNumber() {
|
||||
return number;
|
||||
}
|
||||
|
||||
public GHMilestoneState getState() {
|
||||
return Enum.valueOf(GHMilestoneState.class, state.toUpperCase(Locale.ENGLISH));
|
||||
}
|
||||
/**
|
||||
* Gets root.
|
||||
*
|
||||
* @return the root
|
||||
*/
|
||||
public GitHub getRoot() {
|
||||
return root;
|
||||
}
|
||||
|
||||
public GHMilestone wrap(GHRepository repo) {
|
||||
this.owner = repo;
|
||||
this.root = repo.root;
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* 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;
|
||||
return GitHubClient.parseDate(due_on);
|
||||
}
|
||||
|
||||
/**
|
||||
* When was this milestone closed?
|
||||
*
|
||||
* @return the closed at
|
||||
* @throws IOException
|
||||
* the io exception
|
||||
*/
|
||||
public Date getClosedAt() throws IOException {
|
||||
return GitHubClient.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;
|
||||
}
|
||||
|
||||
public URL getHtmlUrl() {
|
||||
return GitHubClient.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");
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.createRequest().method("DELETE").withUrlPath(getApiRoute()).send();
|
||||
}
|
||||
|
||||
private void edit(String key, Object value) throws IOException {
|
||||
root.createRequest().with(key, value).method("PATCH").withUrlPath(getApiRoute()).send();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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", GitHubClient.printDate(dueOn));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets api route.
|
||||
*
|
||||
* @return the api route
|
||||
*/
|
||||
protected String getApiRoute() {
|
||||
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;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Yusuke Kokubo
|
||||
* The enum GHMilestoneState.
|
||||
*
|
||||
* @author Yusuke Kokubo
|
||||
*/
|
||||
public enum GHMilestoneState {
|
||||
OPEN,
|
||||
CLOSED
|
||||
OPEN, CLOSED
|
||||
}
|
||||
@@ -1,10 +1,9 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
@@ -16,39 +15,110 @@ import java.util.TreeMap;
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
public class GHMyself extends GHUser {
|
||||
|
||||
/**
|
||||
* Returns the read-only list of e-mail addresses configured for you.
|
||||
* Type of repositories returned during listing.
|
||||
*/
|
||||
public enum RepositoryListFilter {
|
||||
/**
|
||||
* All public and private repositories that current user has access or collaborates to
|
||||
*/
|
||||
ALL,
|
||||
/**
|
||||
* Public and private repositories owned by current user
|
||||
*/
|
||||
OWNER,
|
||||
/**
|
||||
* Public repositories that current user has access or collaborates to
|
||||
*/
|
||||
PUBLIC,
|
||||
/**
|
||||
* Private repositories that current user has access or collaborates to
|
||||
*/
|
||||
PRIVATE,
|
||||
/**
|
||||
* Public and private repositories that current user is a member
|
||||
*/
|
||||
MEMBER;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets emails.
|
||||
*
|
||||
* 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 the emails
|
||||
* @throws IOException
|
||||
* the io exception
|
||||
* @deprecated Use {@link #getEmails2()}
|
||||
*/
|
||||
public List<String> getEmails() throws IOException {
|
||||
String[] addresses = root.retrieve().to("/user/emails", String[].class);
|
||||
return Collections.unmodifiableList(Arrays.asList(addresses));
|
||||
List<GHEmail> src = getEmails2();
|
||||
List<String> r = new ArrayList<String>(src.size());
|
||||
for (GHEmail e : src) {
|
||||
r.add(e.getEmail());
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*
|
||||
* @return Always non-null.
|
||||
* @throws IOException
|
||||
* the io exception
|
||||
*/
|
||||
public List<GHEmail> getEmails2() throws IOException {
|
||||
return root.createRequest().withUrlPath("/user/emails").toIterable(GHEmail[].class, null).toList();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @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)));
|
||||
return root.createRequest().withUrlPath("/user/keys").toIterable(GHKey[].class, null).toList();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @return Always non-null.
|
||||
* @throws IOException
|
||||
* the io exception
|
||||
*/
|
||||
public List<GHVerifiedKey> getPublicVerifiedKeys() throws IOException {
|
||||
return root.createRequest()
|
||||
.withUrlPath("/users/" + getLogin() + "/keys")
|
||||
.toIterable(GHVerifiedKey[].class, null)
|
||||
.toList();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
for (GHOrganization o : root.createRequest()
|
||||
.withUrlPath("/user/orgs")
|
||||
.toIterable(GHOrganization[].class, null)
|
||||
.toArray()) {
|
||||
if (names.add(o.getLogin())) // in case of rumoured duplicates in the data
|
||||
orgs.add(root.getOrganization(o.getLogin()));
|
||||
}
|
||||
return orgs;
|
||||
@@ -56,11 +126,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);
|
||||
}
|
||||
@@ -68,24 +142,101 @@ 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.
|
||||
* 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.
|
||||
*/
|
||||
public PagedIterable<GHRepository> listAllRepositories() {
|
||||
return new PagedIterable<GHRepository>() {
|
||||
public PagedIterator<GHRepository> iterator() {
|
||||
return new PagedIterator<GHRepository>(root.retrieve().asIterator("/user/repos", GHRepository[].class)) {
|
||||
@Override
|
||||
protected void wrapUp(GHRepository[] page) {
|
||||
for (GHRepository c : page)
|
||||
c.wrap(root);
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
@Override
|
||||
public PagedIterable<GHRepository> listRepositories() {
|
||||
return listRepositories(30);
|
||||
}
|
||||
|
||||
// public void addEmails(Collection<String> emails) throws IOException {
|
||||
//// new Requester(root,ApiVersion.V3).withCredential().to("/user/emails");
|
||||
// root.retrieveWithAuth3()
|
||||
// }
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @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.
|
||||
*/
|
||||
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.
|
||||
*
|
||||
* @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 root.createRequest()
|
||||
.with("type", repoType)
|
||||
.withUrlPath("/user/repos")
|
||||
.toIterable(GHRepository[].class, item -> item.wrap(root))
|
||||
.withPageSize(pageSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* List all repositories paged iterable.
|
||||
*
|
||||
* @return the paged iterable
|
||||
* @deprecated Use {@link #listRepositories()}
|
||||
*/
|
||||
@Deprecated
|
||||
public PagedIterable<GHRepository> listAllRepositories() {
|
||||
return listRepositories();
|
||||
}
|
||||
|
||||
/**
|
||||
* List your organization memberships
|
||||
*
|
||||
* @return the paged iterable
|
||||
*/
|
||||
public PagedIterable<GHMembership> listOrgMemberships() {
|
||||
return listOrgMemberships(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* List your organization memberships
|
||||
*
|
||||
* @param state
|
||||
* Filter by a specific state
|
||||
* @return the paged iterable
|
||||
*/
|
||||
public PagedIterable<GHMembership> listOrgMemberships(final GHMembership.State state) {
|
||||
return root.createRequest()
|
||||
.with("state", state)
|
||||
.withUrlPath("/user/memberships/orgs")
|
||||
.toIterable(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.createRequest()
|
||||
.withUrlPath("/user/memberships/orgs/" + o.getLogin())
|
||||
.fetch(GHMembership.class)
|
||||
.wrap(root);
|
||||
}
|
||||
|
||||
// public void addEmails(Collection<String> emails) throws IOException {
|
||||
//// new Requester(root,ApiVersion.V3).withCredential().to("/user/emails");
|
||||
// root.retrieveWithAuth3()
|
||||
// }
|
||||
}
|
||||
|
||||
240
src/main/java/org/kohsuke/github/GHNotificationStream.java
Normal file
240
src/main/java/org/kohsuke/github/GHNotificationStream.java
Normal file
@@ -0,0 +1,240 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Date;
|
||||
import java.util.Iterator;
|
||||
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)}.
|
||||
*
|
||||
* <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.
|
||||
*
|
||||
* <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.
|
||||
*
|
||||
* @author Kohsuke Kawaguchi
|
||||
* @see GitHub#listNotifications() GitHub#listNotifications()
|
||||
* @see GHRepository#listNotifications() GHRepository#listNotifications()
|
||||
*/
|
||||
public class GHNotificationStream implements Iterable<GHThread> {
|
||||
private final GitHub root;
|
||||
|
||||
private Boolean all, participating;
|
||||
private String since;
|
||||
private String apiUrl;
|
||||
private boolean nonBlocking = false;
|
||||
|
||||
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;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 = GitHubClient.printDate(dt);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 = root.createRequest()
|
||||
.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.
|
||||
*/
|
||||
private GHThread[] threads = EMPTY_ARRAY;
|
||||
|
||||
/**
|
||||
* Next element in {@link #threads} to return. This counts down.
|
||||
*/
|
||||
private int idx = -1;
|
||||
|
||||
/**
|
||||
* threads whose updated_at is older than this should be ignored.
|
||||
*/
|
||||
private long lastUpdated = -1;
|
||||
|
||||
/**
|
||||
* Next request should have "If-Modified-Since" header with this value.
|
||||
*/
|
||||
private String lastModified;
|
||||
|
||||
/**
|
||||
* When is the next polling allowed?
|
||||
*/
|
||||
private long nextCheckTime = -1;
|
||||
|
||||
private GHThread next;
|
||||
|
||||
public GHThread next() {
|
||||
if (next == null) {
|
||||
next = fetch();
|
||||
if (next == null)
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
|
||||
GHThread r = next;
|
||||
next = null;
|
||||
return r;
|
||||
}
|
||||
|
||||
public boolean hasNext() {
|
||||
if (next == null)
|
||||
next = fetch();
|
||||
return next != null;
|
||||
}
|
||||
|
||||
GHThread fetch() {
|
||||
try {
|
||||
while (true) {// loop until we get new threads to return
|
||||
|
||||
// if we have fetched un-returned threads, use them first
|
||||
while (idx >= 0) {
|
||||
GHThread n = threads[idx--];
|
||||
long nt = n.getUpdatedAt().getTime();
|
||||
if (nt >= lastUpdated) {
|
||||
lastUpdated = nt;
|
||||
return n.wrap(root);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
long waitTime = Math.min(Math.max(nextCheckTime - now, 1000), 60 * 1000);
|
||||
Thread.sleep(waitTime);
|
||||
}
|
||||
|
||||
req.setHeader("If-Modified-Since", lastModified);
|
||||
|
||||
Requester requester = req.withUrlPath(apiUrl);
|
||||
GitHubResponse<GHThread[]> response = ((GitHubPageContentsIterable<GHThread>) requester
|
||||
.toIterable(GHThread[].class, null)).toResponse();
|
||||
threads = response.body();
|
||||
|
||||
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;
|
||||
|
||||
nextCheckTime = calcNextCheckTime(response);
|
||||
lastModified = response.headerField("Last-Modified");
|
||||
}
|
||||
} catch (IOException | InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private long calcNextCheckTime(GitHubResponse<GHThread[]> response) {
|
||||
String v = response.headerField("X-Poll-Interval");
|
||||
if (v == null)
|
||||
v = "60";
|
||||
long seconds = Integer.parseInt(v);
|
||||
return System.currentTimeMillis() + seconds * 1000;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 = root.createRequest();
|
||||
if (timestamp >= 0)
|
||||
req.with("last_read_at", GitHubClient.printDate(new Date(timestamp)));
|
||||
req.withUrlPath(apiUrl).fetchHttpStatusCode();
|
||||
}
|
||||
|
||||
private static final GHThread[] EMPTY_ARRAY = new GHThread[0];
|
||||
}
|
||||
10
src/main/java/org/kohsuke/github/GHOTPRequiredException.java
Normal file
10
src/main/java/org/kohsuke/github/GHOTPRequiredException.java
Normal 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 {
|
||||
// ...
|
||||
}
|
||||
187
src/main/java/org/kohsuke/github/GHObject.java
Normal file
187
src/main/java/org/kohsuke/github/GHObject.java
Normal file
@@ -0,0 +1,187 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JacksonInject;
|
||||
import com.infradna.tool.bridge_method_injector.WithBridgeMethods;
|
||||
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||
import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.net.URL;
|
||||
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")
|
||||
public abstract class GHObject {
|
||||
/**
|
||||
* Capture response HTTP headers on the state object.
|
||||
*/
|
||||
protected transient Map<String, List<String>> responseHeaderFields;
|
||||
|
||||
private String url;
|
||||
|
||||
private long id;
|
||||
private String nodeId;
|
||||
private String createdAt;
|
||||
private String updatedAt;
|
||||
|
||||
GHObject() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by Jackson
|
||||
*
|
||||
* @param responseInfo
|
||||
* the {@link GitHubResponse.ResponseInfo} to get headers from.
|
||||
*/
|
||||
@JacksonInject
|
||||
protected void setResponseHeaderFields(@CheckForNull GitHubResponse.ResponseInfo responseInfo) {
|
||||
if (responseInfo != null) {
|
||||
responseHeaderFields = responseInfo.headers();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* <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.
|
||||
*
|
||||
* @return a map of header names to value lists
|
||||
*/
|
||||
@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")
|
||||
public Date getCreatedAt() throws IOException {
|
||||
return GitHubClient.parseDate(createdAt);
|
||||
}
|
||||
|
||||
@SuppressFBWarnings(value = "UPM_UNCALLED_PRIVATE_METHOD", justification = "Bridge method of getCreatedAt")
|
||||
private Object createdAtStr(Date id, Class type) {
|
||||
return createdAt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets url.
|
||||
*
|
||||
* @return API URL of this object.
|
||||
*/
|
||||
@WithBridgeMethods(value = String.class, adapterMethod = "urlToString")
|
||||
public URL getUrl() {
|
||||
return GitHubClient.parseURL(url);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets html url.
|
||||
*
|
||||
* @return URL of this object for humans, which renders some HTML.
|
||||
* @throws IOException
|
||||
* on error
|
||||
*/
|
||||
@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 GitHubClient.parseDate(updatedAt);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Global node_id from Github object.
|
||||
*
|
||||
* @see <a href="https://developer.github.com/v4/guides/using-global-node-ids/">Using Global Node IDs</a>
|
||||
*
|
||||
* @return Global Node ID.
|
||||
*/
|
||||
public String getNodeId() {
|
||||
return nodeId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets id.
|
||||
*
|
||||
* @return Unique ID number of this resource.
|
||||
*/
|
||||
@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)
|
||||
return String.valueOf(id);
|
||||
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();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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() {
|
||||
return new ReflectionToStringBuilder(this, TOSTRING_STYLE, null, null, false, false) {
|
||||
@Override
|
||||
protected boolean accept(Field field) {
|
||||
return super.accept(field) && !field.isAnnotationPresent(SkipFromToString.class);
|
||||
}
|
||||
}.toString();
|
||||
}
|
||||
|
||||
private static final ToStringStyle TOSTRING_STYLE = new ToStringStyle() {
|
||||
{
|
||||
this.setUseShortClassName(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void append(StringBuffer buffer, String fieldName, Object value, Boolean fullDetail) {
|
||||
// skip unimportant properties. '_' is a heuristics as important properties tend to have short names
|
||||
if (fieldName.contains("_"))
|
||||
return;
|
||||
// avoid recursing other GHObject
|
||||
if (value instanceof GHObject)
|
||||
return;
|
||||
// likewise no point in showing root
|
||||
if (value instanceof GitHub)
|
||||
return;
|
||||
|
||||
super.append(buffer, fieldName, value, fullDetail);
|
||||
}
|
||||
};
|
||||
}
|
||||
27
src/main/java/org/kohsuke/github/GHOrgHook.java
Normal file
27
src/main/java/org/kohsuke/github/GHOrgHook.java
Normal file
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* © Copyright 2015 - SourceClear Inc
|
||||
*/
|
||||
|
||||
package org.kohsuke.github;
|
||||
|
||||
class GHOrgHook extends GHHook {
|
||||
/**
|
||||
* Organization that the hook belongs to.
|
||||
*/
|
||||
transient GHOrganization organization;
|
||||
|
||||
GHOrgHook wrap(GHOrganization owner) {
|
||||
this.organization = owner;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
GitHub getRoot() {
|
||||
return organization.root;
|
||||
}
|
||||
|
||||
@Override
|
||||
String getApiRoute() {
|
||||
return String.format("/orgs/%s/hooks/%d", organization.getLogin(), getId());
|
||||
}
|
||||
}
|
||||
@@ -1,69 +1,269 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.AbstractList;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
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.
|
||||
* @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 {
|
||||
return createRepository(name,description,homepage,getTeams().get(team),isPublic);
|
||||
@Deprecated
|
||||
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);
|
||||
return createRepository(name, description, homepage, t, isPublic);
|
||||
}
|
||||
|
||||
public GHRepository createRepository(String name, String description, String homepage, GHTeam team, boolean isPublic) throws IOException {
|
||||
// such API doesn't exist, so fall back to HTML scraping
|
||||
return new Requester(root)
|
||||
.with("name", name).with("description", description).with("homepage", homepage)
|
||||
.with("public", isPublic).with("team_id",team.getId()).to("/orgs/"+login+"/repos", GHRepository.class).wrap(root);
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
@Deprecated
|
||||
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();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 create a repository.
|
||||
*
|
||||
* @param name
|
||||
* the name
|
||||
* @return the gh create repository builder
|
||||
*/
|
||||
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 {
|
||||
GHTeam[] teams = root.retrieve().to("/orgs/" + login + "/teams", GHTeam[].class);
|
||||
Map<String,GHTeam> r = new TreeMap<String, GHTeam>();
|
||||
for (GHTeam t : teams) {
|
||||
r.put(t.getName(),t.wrapUp(this));
|
||||
public Map<String, GHTeam> getTeams() throws IOException {
|
||||
Map<String, GHTeam> r = new TreeMap<String, GHTeam>();
|
||||
for (GHTeam t : listTeams()) {
|
||||
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 root.createRequest()
|
||||
.withUrlPath(String.format("/orgs/%s/teams", login))
|
||||
.toIterable(GHTeam[].class, item -> item.wrapUp(this));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a single team by ID.
|
||||
*
|
||||
* @param teamId
|
||||
* id of the team that we want to query for
|
||||
* @return the team
|
||||
* @throws IOException
|
||||
* the io exception
|
||||
*
|
||||
* @deprecated Use {@link GHOrganization#getTeam(long)}
|
||||
*/
|
||||
@Deprecated
|
||||
public GHTeam getTeam(int teamId) throws IOException {
|
||||
return getTeam((long) teamId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a single team by ID.
|
||||
*
|
||||
* @param teamId
|
||||
* id of the team that we want to query for
|
||||
* @return the team
|
||||
* @throws IOException
|
||||
* the io exception
|
||||
*
|
||||
* @see <a href= "https://developer.github.com/v3/teams/#get-team-by-name">documentation</a>
|
||||
*/
|
||||
public GHTeam getTeam(long teamId) throws IOException {
|
||||
return root.createRequest()
|
||||
.withUrlPath(String.format("/organizations/%d/team/%d", getId(), teamId))
|
||||
.fetch(GHTeam.class)
|
||||
.wrapUp(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))
|
||||
return t;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @see <a href= "https://developer.github.com/v3/teams/#get-team-by-name">documentation</a>
|
||||
*/
|
||||
public GHTeam getTeamBySlug(String slug) throws IOException {
|
||||
return root.createRequest()
|
||||
.withUrlPath(String.format("/orgs/%s/teams/%s", login, slug))
|
||||
.fetch(GHTeam.class)
|
||||
.wrapUp(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.createRequest()
|
||||
.method("PUT")
|
||||
.with("role", role.name().toLowerCase())
|
||||
.withUrlPath("/orgs/" + login + "/memberships/" + user.getLogin())
|
||||
.send();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.createRequest().withUrlPath("/orgs/" + login + "/members/" + user.getLogin()).send();
|
||||
return true;
|
||||
} catch (IOException ignore) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a member of the organisation - which will remove them from all teams, and remove their access to the
|
||||
* organization’s repositories.
|
||||
*
|
||||
* @param user
|
||||
* the user
|
||||
* @throws IOException
|
||||
* the io exception
|
||||
*/
|
||||
public void remove(GHUser user) throws IOException {
|
||||
root.createRequest().method("DELETE").withUrlPath("/orgs/" + login + "/members/" + user.getLogin()).send();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 {
|
||||
root.retrieve().to("/orgs/" + login + "/public_members/" + user.getLogin());
|
||||
root.createRequest().withUrlPath("/orgs/" + login + "/public_members/" + user.getLogin()).send();
|
||||
return true;
|
||||
} catch (IOException ignore) {
|
||||
return false;
|
||||
@@ -72,71 +272,272 @@ 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);
|
||||
root.createRequest().method("PUT").withUrlPath("/orgs/" + login + "/public_members/" + u.getLogin()).send();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets members.
|
||||
*
|
||||
* @return the members
|
||||
* @throws IOException
|
||||
* the io exception
|
||||
* @deprecated use {@link #listMembers()}
|
||||
*/
|
||||
public List<GHUser> getMembers() throws IOException {
|
||||
return listMembers().toList();
|
||||
}
|
||||
|
||||
/**
|
||||
* All the members of this organization.
|
||||
*
|
||||
* @return the paged iterable
|
||||
* @throws IOException
|
||||
* the io exception
|
||||
*/
|
||||
public List<GHUser> getMembers() throws IOException {
|
||||
return new AbstractList<GHUser>() {
|
||||
// these are shallow objects with only some limited values filled out
|
||||
// TODO: it's better to allow objects to fill themselves in later when missing values are requested
|
||||
final GHUser[] shallow = root.retrieve().to("/orgs/" + login + "/members", GHUser[].class);
|
||||
public PagedIterable<GHUser> listMembers() throws IOException {
|
||||
return listMembers("members");
|
||||
}
|
||||
|
||||
@Override
|
||||
public GHUser get(int index) {
|
||||
try {
|
||||
return root.getUser(shallow[index].getLogin());
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 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");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return shallow.length;
|
||||
}
|
||||
};
|
||||
private PagedIterable<GHUser> listMembers(String suffix) throws IOException {
|
||||
return listMembers(suffix, null, 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, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* List members with specified role paged iterable.
|
||||
*
|
||||
* @param role
|
||||
* the role
|
||||
* @return the paged iterable
|
||||
* @throws IOException
|
||||
* the io exception
|
||||
*/
|
||||
public PagedIterable<GHUser> listMembersWithRole(String role) throws IOException {
|
||||
return listMembers("members", null, role);
|
||||
}
|
||||
|
||||
private PagedIterable<GHUser> listMembers(final String suffix, final String filter, String role)
|
||||
throws IOException {
|
||||
return root.createRequest()
|
||||
.withUrlPath(String.format("/orgs/%s/%s", login, suffix))
|
||||
.with("filter", filter)
|
||||
.with("role", role)
|
||||
.toIterable(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);
|
||||
root.createRequest().method("DELETE").withUrlPath("/orgs/" + login + "/public_members/" + u.getLogin()).send();
|
||||
}
|
||||
|
||||
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.createRequest()
|
||||
.withPreview(INERTIA)
|
||||
.with("state", status)
|
||||
.withUrlPath(String.format("/orgs/%s/projects", login))
|
||||
.toIterable(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.createRequest()
|
||||
.method("POST")
|
||||
.withPreview(INERTIA)
|
||||
.with("name", name)
|
||||
.with("body", body)
|
||||
.withUrlPath(String.format("/orgs/%s/projects", login))
|
||||
.fetch(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)}
|
||||
*/
|
||||
@Deprecated
|
||||
public GHTeam createTeam(String name, Permission p, Collection<GHRepository> repositories) throws IOException {
|
||||
Requester post = new Requester(root).with("name", name).with("permission", p.name().toLowerCase());
|
||||
Requester post = root.createRequest().method("POST").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);
|
||||
return post.method("POST").to("/orgs/" + login + "/teams", GHTeam.class).wrapUp(this);
|
||||
post.with("repo_names", repo_names);
|
||||
return post.withUrlPath("/orgs/" + login + "/teams").fetch(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)}
|
||||
*/
|
||||
@Deprecated
|
||||
public GHTeam createTeam(String name, Permission p, GHRepository... repositories) throws IOException {
|
||||
return createTeam(name,p, Arrays.asList(repositories));
|
||||
return createTeam(name, p, Arrays.asList(repositories));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new team and assigns the repositories.
|
||||
*
|
||||
* @param name
|
||||
* the name
|
||||
* @param repositories
|
||||
* the repositories
|
||||
* @return the gh team
|
||||
* @throws IOException
|
||||
* the io exception
|
||||
* @deprecated Use {@link #createTeam(String)} that uses a builder pattern to let you control every aspect.
|
||||
*/
|
||||
@Deprecated
|
||||
public GHTeam createTeam(String name, Collection<GHRepository> repositories) throws IOException {
|
||||
Requester post = root.createRequest().method("POST").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.withUrlPath("/orgs/" + login + "/teams").fetch(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
|
||||
* @deprecated Use {@link #createTeam(String)} that uses a builder pattern to let you control every aspect.
|
||||
*/
|
||||
@Deprecated
|
||||
public GHTeam createTeam(String name, GHRepository... repositories) throws IOException {
|
||||
return createTeam(name, Arrays.asList(repositories));
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts a builder that creates a new team.
|
||||
*
|
||||
* <p>
|
||||
* You use the returned builder to set various properties, then call {@link GHTeamBuilder#create()} to finally
|
||||
* create a team.
|
||||
*
|
||||
* @param name
|
||||
* the name
|
||||
* @return the gh create repository builder
|
||||
*/
|
||||
public GHTeamBuilder createTeam(String name) {
|
||||
return new GHTeamBuilder(root, login, name);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* 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>();
|
||||
for (GHRepository repository : listRepositories()) {
|
||||
for (GHRepository repository : listRepositories(100)) {
|
||||
repository.wrap(root);
|
||||
List<GHPullRequest> pullRequests = repository.getPullRequests(GHIssueState.OPEN);
|
||||
if (pullRequests.size() > 0) {
|
||||
@@ -148,6 +549,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>();
|
||||
@@ -156,4 +561,102 @@ public class GHOrganization extends GHPerson {
|
||||
}
|
||||
return all;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lists events performed by a user (this includes private events if the caller is authenticated.
|
||||
*/
|
||||
public PagedIterable<GHEventInfo> listEvents() throws IOException {
|
||||
return root.createRequest()
|
||||
.withUrlPath(String.format("/orgs/%s/events", login))
|
||||
.toIterable(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.
|
||||
*
|
||||
* Unlike {@link #getRepositories()}, this does not wait until all the repositories are returned.
|
||||
*/
|
||||
@Override
|
||||
public PagedIterable<GHRepository> listRepositories(final int pageSize) {
|
||||
return root.createRequest()
|
||||
.withUrlPath("/orgs/" + login + "/repos")
|
||||
.toIterable(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
|
||||
*
|
||||
* @param name
|
||||
* Type of the hook to be created. See https://api.github.com/hooks for possible names.
|
||||
* @param config
|
||||
* The configuration hash.
|
||||
* @param events
|
||||
* 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 {
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
|
||||
72
src/main/java/org/kohsuke/github/GHPermission.java
Normal file
72
src/main/java/org/kohsuke/github/GHPermission.java
Normal file
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright 2016 CloudBees, Inc.
|
||||
*
|
||||
* 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.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>
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
void wrapUp(GitHub root) {
|
||||
if (user != null) {
|
||||
user.root = root;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
10
src/main/java/org/kohsuke/github/GHPermissionType.java
Normal file
10
src/main/java/org/kohsuke/github/GHPermissionType.java
Normal file
@@ -0,0 +1,10 @@
|
||||
package org.kohsuke.github;
|
||||
|
||||
/**
|
||||
* The enum GHPermissionType.
|
||||
*
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
public enum GHPermissionType {
|
||||
ADMIN, WRITE, READ, NONE
|
||||
}
|
||||
@@ -2,163 +2,200 @@ package org.kohsuke.github;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.TreeMap;
|
||||
|
||||
/**
|
||||
* Common part of {@link GHUser} and {@link GHOrganization}.
|
||||
*
|
||||
*
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
public abstract class GHPerson {
|
||||
/*package almost final*/ GitHub root;
|
||||
public abstract class GHPerson extends GHObject {
|
||||
/* 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, url, gravatar_id;
|
||||
protected int id;
|
||||
protected String login, avatar_url;
|
||||
|
||||
// other fields (that only show up in full data)
|
||||
protected String location,blog,email,name,created_at,company;
|
||||
protected String location, blog, email, name, company, type;
|
||||
protected String html_url;
|
||||
protected int followers,following,public_repos,public_gists;
|
||||
protected int followers, following, public_repos, public_gists;
|
||||
protected boolean site_admin;
|
||||
|
||||
/*package*/ GHPerson wrapUp(GitHub root) {
|
||||
// other fields (that only show up in full data) that require privileged scope
|
||||
protected Integer total_private_repos;
|
||||
|
||||
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 void populate() throws IOException {
|
||||
if (created_at!=null) return; // already populated
|
||||
|
||||
root.retrieve().to(url, this);
|
||||
protected synchronized void populate() throws IOException {
|
||||
if (super.getCreatedAt() != null) {
|
||||
return; // already populated
|
||||
}
|
||||
if (root == null || root.isOffline()) {
|
||||
return; // cannot populate, will have to live with what we have
|
||||
}
|
||||
URL url = getUrl();
|
||||
if (url != null) {
|
||||
root.createRequest().setRawUrlPath(url.toString()).fetchInto(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the repositories this user owns.
|
||||
* Gets the public repositories this user owns.
|
||||
*
|
||||
* <p>
|
||||
* 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>();
|
||||
for (List<GHRepository> batch : iterateRepositories(100)) {
|
||||
for (GHRepository r : batch)
|
||||
repositories.put(r.getName(),r);
|
||||
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);
|
||||
}
|
||||
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() {
|
||||
return new PagedIterator<GHRepository>(root.retrieve().asIterator("/users/" + login + "/repos?per_page=" + pageSize, GHRepository[].class)) {
|
||||
@Override
|
||||
protected void wrapUp(GHRepository[] page) {
|
||||
for (GHRepository c : page)
|
||||
c.wrap(root);
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
return root.createRequest()
|
||||
.withUrlPath("/users/" + login + "/repos")
|
||||
.toIterable(GHRepository[].class, item -> item.wrap(root))
|
||||
.withPageSize(pageSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads repository list in a pagenated fashion.
|
||||
*
|
||||
* Loads repository list in a paginated fashion.
|
||||
*
|
||||
* <p>
|
||||
* For a person with a lot of repositories, GitHub returns the list of repositories in a pagenated 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}.
|
||||
* 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}.
|
||||
*
|
||||
* @deprecated
|
||||
* Use {@link #listRepositories()}
|
||||
* @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);
|
||||
|
||||
return new Iterator<List<GHRepository>>() {
|
||||
public boolean hasNext() {
|
||||
return pager.hasNext();
|
||||
}
|
||||
|
||||
public List<GHRepository> next() {
|
||||
GHRepository[] batch = pager.next();
|
||||
for (GHRepository r : batch)
|
||||
r.root = root;
|
||||
return Arrays.asList(batch);
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
};
|
||||
return () -> {
|
||||
final PagedIterator<GHRepository> pager;
|
||||
try {
|
||||
GitHubPageIterator<GHRepository[]> iterator = GitHubPageIterator.create(root.getClient(),
|
||||
GHRepository[].class,
|
||||
root.createRequest().withUrlPath("users", login, "repos").build(),
|
||||
pageSize);
|
||||
pager = new PagedIterator<>(iterator, item -> item.wrap(root));
|
||||
} catch (MalformedURLException e) {
|
||||
throw new GHException("Unable to build GitHub API URL", e);
|
||||
}
|
||||
|
||||
return new Iterator<List<GHRepository>>() {
|
||||
public boolean hasNext() {
|
||||
return pager.hasNext();
|
||||
}
|
||||
|
||||
public List<GHRepository> next() {
|
||||
return pager.nextPage();
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 {
|
||||
return root.retrieve().to("/repos/" + login + '/' + name, GHRepository.class).wrap(root);
|
||||
return root.createRequest()
|
||||
.withUrlPath("/repos/" + login + '/' + name)
|
||||
.fetch(GHRepository.class)
|
||||
.wrap(root);
|
||||
} catch (FileNotFoundException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
@Deprecated
|
||||
public String getGravatarId() {
|
||||
return gravatar_id;
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string like 'https://secure.gravatar.com/avatar/0cb9832a01c22c083390f3c5dcb64105'
|
||||
* that indicates the avatar image URL.
|
||||
* Returns a string of the avatar image URL.
|
||||
*
|
||||
* @return the avatar url
|
||||
*/
|
||||
public String getAvatarUrl() {
|
||||
if (avatar_url!=null)
|
||||
return avatar_url;
|
||||
if (gravatar_id!=null)
|
||||
return "https://secure.gravatar.com/avatar/"+gravatar_id;
|
||||
return null;
|
||||
return avatar_url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the login ID of this user, like 'kohsuke'
|
||||
*
|
||||
* @return the login
|
||||
*/
|
||||
public String getLogin() {
|
||||
return login;
|
||||
@@ -166,6 +203,10 @@ public abstract class GHPerson {
|
||||
|
||||
/**
|
||||
* 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();
|
||||
@@ -174,6 +215,10 @@ public abstract class GHPerson {
|
||||
|
||||
/**
|
||||
* 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();
|
||||
@@ -182,57 +227,136 @@ public abstract class GHPerson {
|
||||
|
||||
/**
|
||||
* Gets the location of this user, like "Santa Clara, California"
|
||||
*
|
||||
* @return the location
|
||||
* @throws IOException
|
||||
* the io exception
|
||||
*/
|
||||
public String getLocation() throws IOException {
|
||||
populate();
|
||||
return location;
|
||||
}
|
||||
|
||||
public String getCreatedAt() throws IOException {
|
||||
public Date getCreatedAt() throws IOException {
|
||||
populate();
|
||||
return created_at;
|
||||
return super.getCreatedAt();
|
||||
}
|
||||
|
||||
public Date getUpdatedAt() throws IOException {
|
||||
populate();
|
||||
return super.getUpdatedAt();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the blog URL of this user.
|
||||
*
|
||||
* @return the blog
|
||||
* @throws IOException
|
||||
* the io exception
|
||||
*/
|
||||
public String getBlog() throws IOException {
|
||||
populate();
|
||||
return blog;
|
||||
}
|
||||
|
||||
@Override
|
||||
public URL getHtmlUrl() {
|
||||
return GitHubClient.parseURL(html_url);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* What appears to be a GitHub internal unique number that identifies this user.
|
||||
* Gets followers count.
|
||||
*
|
||||
* @return the followers count
|
||||
* @throws IOException
|
||||
* the io exception
|
||||
*/
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public int getFollowersCount() throws IOException {
|
||||
populate();
|
||||
return followers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the type. This is either "User" or "Organization".
|
||||
*
|
||||
* @return the type
|
||||
* @throws IOException
|
||||
* the io exception
|
||||
*/
|
||||
public String getType() throws IOException {
|
||||
populate();
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the site_admin field
|
||||
*
|
||||
* @return the site_admin field
|
||||
* @throws IOException
|
||||
* the io exception
|
||||
*/
|
||||
public boolean isSiteAdmin() throws IOException {
|
||||
populate();
|
||||
return site_admin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets total private repo count.
|
||||
*
|
||||
* @return the total private repo count
|
||||
* @throws IOException
|
||||
* the io exception
|
||||
*/
|
||||
public Optional<Integer> getTotalPrivateRepoCount() throws IOException {
|
||||
populate();
|
||||
return Optional.ofNullable(total_private_repos);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,36 +6,73 @@ import java.util.HashSet;
|
||||
|
||||
/**
|
||||
* Set of {@link GHPerson} with helper lookup methods.
|
||||
*
|
||||
*
|
||||
* @param <T>
|
||||
* the type parameter
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
public final class GHPersonSet<T extends GHPerson> extends HashSet<T> {
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user