Skip to content

Commit 7304566

Browse files
committed
Update GitCheck to include error handling and move to java 17.
1 parent ce07d49 commit 7304566

27 files changed

+975
-228
lines changed

build.gradle.kts

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
plugins {
22
`java-library`
33
`maven-publish`
4-
id("com.github.johnrengelman.shadow") version "8.1.0"
54
}
65

76
group = "com.eternalcode"
@@ -11,51 +10,50 @@ val artifactId = "gitcheck"
1110
java {
1211
withJavadocJar()
1312
withSourcesJar()
14-
15-
sourceCompatibility = JavaVersion.VERSION_1_9
16-
targetCompatibility = JavaVersion.VERSION_1_9
13+
sourceCompatibility = JavaVersion.VERSION_17
14+
targetCompatibility = JavaVersion.VERSION_17
1715
}
1816

1917
repositories {
2018
mavenCentral()
2119
}
2220

2321
dependencies {
24-
// https://mvnrepository.com/artifact/com.googlecode.json-simple/json-simple
2522
api("com.googlecode.json-simple:json-simple:1.1.1") {
2623
exclude(group = "junit")
2724
}
28-
29-
api("org.jetbrains:annotations:24.0.1")
25+
api("org.jetbrains:annotations:26.0.2")
3026

3127
testImplementation("org.junit.jupiter:junit-jupiter-api:5.9.2")
3228
testImplementation("nl.jqno.equalsverifier:equalsverifier:3.14.1")
3329
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.9.2")
3430
}
3531

3632
publishing {
37-
publications {
38-
create<MavenPublication>("maven") {
39-
groupId = "$group"
40-
artifactId = artifactId
41-
version = "${project.version}"
42-
43-
from(components["java"])
44-
}
45-
}
4633
repositories {
34+
mavenLocal()
35+
4736
maven {
48-
name = "eternalcode-repository"
4937
url = uri("https://repo.eternalcode.pl/releases")
5038

39+
if (version.toString().endsWith("-SNAPSHOT")) {
40+
url = uri("https://repo.eternalcode.pl/snapshots")
41+
}
42+
5143
credentials {
52-
username = System.getenv("ETERNALCODE_REPO_USERNAME")
53-
password = System.getenv("ETERNALCODE_REPO_PASSWORD")
44+
username = System.getenv("ETERNAL_CODE_MAVEN_USERNAME")
45+
password = System.getenv("ETERNAL_CODE_MAVEN_PASSWORD")
5446
}
5547
}
5648
}
49+
50+
publications {
51+
create<MavenPublication>("maven") {
52+
from(components["java"])
53+
}
54+
}
5755
}
5856

59-
tasks.getByName<Test>("test") {
57+
tasks.test {
6058
useJUnitPlatform()
6159
}

gradle.properties

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
org.gradle.configuration-cache=true
2+
org.gradle.caching=true
3+
org.gradle.parallel=true
4+
org.gradle.vfs.watch=false
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
distributionBase=GRADLE_USER_HOME
22
distributionPath=wrapper/dists
3-
distributionUrl=https\://services.gradle.org/distributions/gradle-8.0.2-bin.zip
3+
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip
44
networkTimeout=10000
55
zipStoreBase=GRADLE_USER_HOME
66
zipStorePath=wrapper/dists

src/main/java/com/eternalcode/gitcheck/GitCheck.java

Lines changed: 123 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,11 @@
1010

1111
/**
1212
* Service for checking if the latest release is up to date.
13-
* <p>
14-
* This service uses {@link GitReleaseProvider} to get the latest release and compares it with the current tag.
15-
* The current tag is provided by {@link GitTag#of(String)}
16-
* <br>
1713
*/
1814
public class GitCheck {
1915

2016
private final GitReleaseProvider versionProvider;
17+
private GitCheckErrorHandler errorHandler;
2118

2219
/**
2320
* Creates a new instance of {@link GitCheck} with the default {@link GitHubReleaseProvider}.
@@ -34,25 +31,92 @@ public GitCheck() {
3431
public GitCheck(@NotNull GitReleaseProvider versionProvider) {
3532
Preconditions.notNull(versionProvider, "release provider");
3633
this.versionProvider = versionProvider;
34+
this.errorHandler = GitCheckErrorHandler.noOp();
35+
}
36+
37+
/**
38+
* Sets the error handler for this GitCheck instance.
39+
*
40+
* @param errorHandler the error handler
41+
* @return this instance for method chaining
42+
*/
43+
@NotNull
44+
public GitCheck onError(@NotNull GitCheckErrorHandler errorHandler) {
45+
Preconditions.notNull(errorHandler, "error handler");
46+
this.errorHandler = errorHandler;
47+
return this;
48+
}
49+
50+
/**
51+
* Sets error handler for specific status codes.
52+
*
53+
* @param statusCode the status code to handle
54+
* @param handler the handler for this status code
55+
* @return this instance for method chaining
56+
*/
57+
@NotNull
58+
public GitCheck onStatusCode(int statusCode, @NotNull GitCheckErrorHandler handler) {
59+
Preconditions.notNull(handler, "handler");
60+
61+
GitCheckErrorHandler previousHandler = this.errorHandler;
62+
this.errorHandler = error -> {
63+
if (error.hasStatusCode() && error.getStatusCode() == statusCode) {
64+
handler.handle(error);
65+
}
66+
else {
67+
previousHandler.handle(error);
68+
}
69+
};
70+
return this;
71+
}
72+
73+
/**
74+
* Sets error handler for specific error types.
75+
*
76+
* @param errorType the error type to handle
77+
* @param handler the handler for this error type
78+
* @return this instance for method chaining
79+
*/
80+
@NotNull
81+
public GitCheck onErrorType(@NotNull GitCheckErrorType errorType, @NotNull GitCheckErrorHandler handler) {
82+
Preconditions.notNull(errorType, "error type");
83+
Preconditions.notNull(handler, "handler");
84+
85+
GitCheckErrorHandler previousHandler = this.errorHandler;
86+
this.errorHandler = error -> {
87+
if (error.getType() == errorType) {
88+
handler.handle(error);
89+
}
90+
else {
91+
previousHandler.handle(error);
92+
}
93+
};
94+
return this;
3795
}
3896

3997
/**
4098
* Gets the latest release for the given repository.
4199
*
42100
* @param repository the repository
43-
* @return the latest release
101+
* @return the latest release, or null if error occurred
44102
*/
45103
@NotNull
46-
public GitRelease getLatestRelease(@NotNull GitRepository repository) {
104+
public GitCheckResult getLatestRelease(@NotNull GitRepository repository) {
47105
Preconditions.notNull(repository, "repository");
48106

49-
return this.versionProvider.getLatestRelease(repository);
107+
try {
108+
GitRelease release = this.versionProvider.getLatestRelease(repository);
109+
return GitCheckResult.success(release, GitTag.of("unknown"));
110+
}
111+
catch (Exception exception) {
112+
GitCheckError error = mapExceptionToError(exception);
113+
this.errorHandler.handle(error);
114+
return GitCheckResult.failure(error);
115+
}
50116
}
51117

52118
/**
53119
* Creates a new instance of {@link GitCheckResult} for the given repository and tag.
54-
* Result contains the latest release and the current tag.
55-
* Use {@link GitCheckResult#isUpToDate()} to check if the latest release is up to date.
56120
*
57121
* @param repository the repository
58122
* @param currentTag the current tag
@@ -63,8 +127,55 @@ public GitCheckResult checkRelease(@NotNull GitRepository repository, @NotNull G
63127
Preconditions.notNull(repository, "repository");
64128
Preconditions.notNull(currentTag, "current tag");
65129

66-
GitRelease latestRelease = this.getLatestRelease(repository);
67-
return new GitCheckResult(latestRelease, currentTag);
130+
try {
131+
GitRelease latestRelease = this.versionProvider.getLatestRelease(repository);
132+
return GitCheckResult.success(latestRelease, currentTag);
133+
}
134+
catch (Exception exception) {
135+
GitCheckError error = mapExceptionToError(exception);
136+
this.errorHandler.handle(error);
137+
return GitCheckResult.failure(error);
138+
}
68139
}
69140

70-
}
141+
private GitCheckError mapExceptionToError(Exception exception) {
142+
String message = exception.getMessage();
143+
144+
if (message.contains("404")) {
145+
if (message.contains("repository")) {
146+
return new GitCheckError(GitCheckErrorType.REPOSITORY_NOT_FOUND, message, 404, exception);
147+
}
148+
else {
149+
return new GitCheckError(GitCheckErrorType.RELEASE_NOT_FOUND, message, 404, exception);
150+
}
151+
}
152+
153+
if (message.contains("403")) {
154+
return new GitCheckError(GitCheckErrorType.RATE_LIMIT_EXCEEDED, message, 403, exception);
155+
}
156+
157+
if (message.contains("401")) {
158+
return new GitCheckError(GitCheckErrorType.AUTHENTICATION_REQUIRED, message, 401, exception);
159+
}
160+
161+
if (message.contains("Unexpected response code")) {
162+
try {
163+
int statusCode = Integer.parseInt(message.replaceAll(".*: (\\d+).*", "$1"));
164+
return new GitCheckError(GitCheckErrorType.HTTP_ERROR, message, statusCode, exception);
165+
}
166+
catch (NumberFormatException e) {
167+
return new GitCheckError(GitCheckErrorType.HTTP_ERROR, message, exception);
168+
}
169+
}
170+
171+
if (message.contains("Invalid JSON") || message.contains("not a JSON object")) {
172+
return new GitCheckError(GitCheckErrorType.INVALID_RESPONSE, message, exception);
173+
}
174+
175+
if (exception instanceof java.io.IOException) {
176+
return new GitCheckError(GitCheckErrorType.NETWORK_ERROR, message, exception);
177+
}
178+
179+
return new GitCheckError(GitCheckErrorType.UNKNOWN, message, exception);
180+
}
181+
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package com.eternalcode.gitcheck;
2+
3+
import org.jetbrains.annotations.NotNull;
4+
import org.jetbrains.annotations.Nullable;
5+
6+
/**
7+
* Represents an error that occurred during git check operation.
8+
*/
9+
public class GitCheckError {
10+
11+
private final GitCheckErrorType type;
12+
private final String message;
13+
private final int statusCode;
14+
private final Throwable cause;
15+
16+
public GitCheckError(
17+
@NotNull GitCheckErrorType type,
18+
@NotNull String message,
19+
int statusCode,
20+
@Nullable Throwable cause
21+
) {
22+
this.type = type;
23+
this.message = message;
24+
this.statusCode = statusCode;
25+
this.cause = cause;
26+
}
27+
28+
public GitCheckError(@NotNull GitCheckErrorType type, @NotNull String message, @Nullable Throwable cause) {
29+
this(type, message, -1, cause);
30+
}
31+
32+
public GitCheckError(@NotNull GitCheckErrorType type, @NotNull String message) {
33+
this(type, message, -1, null);
34+
}
35+
36+
@NotNull
37+
public GitCheckErrorType getType() {
38+
return type;
39+
}
40+
41+
@NotNull
42+
public String getMessage() {
43+
return message;
44+
}
45+
46+
public int getStatusCode() {
47+
return statusCode;
48+
}
49+
50+
@Nullable
51+
public Throwable getCause() {
52+
return cause;
53+
}
54+
55+
public boolean hasStatusCode() {
56+
return statusCode != -1;
57+
}
58+
59+
@Override
60+
public String toString() {
61+
return "GitCheckError{" +
62+
"type=" + type +
63+
", message='" + message + '\'' +
64+
(hasStatusCode() ? ", statusCode=" + statusCode : "") +
65+
'}';
66+
}
67+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package com.eternalcode.gitcheck;
2+
3+
import org.jetbrains.annotations.NotNull;
4+
5+
/**
6+
* Interface for handling git check errors.
7+
*/
8+
@FunctionalInterface
9+
public interface GitCheckErrorHandler {
10+
11+
/**
12+
* Creates a no-op error handler.
13+
*
14+
* @return no-op error handler
15+
*/
16+
@NotNull
17+
static GitCheckErrorHandler noOp() {
18+
return error -> {};
19+
}
20+
/**
21+
* Creates an error handler that prints to console.
22+
*
23+
* @return console error handler
24+
*/
25+
@NotNull
26+
static GitCheckErrorHandler console() {
27+
return error -> System.err.println("GitCheck Error: " + error);
28+
}
29+
/**
30+
* Creates an error handler that throws exceptions.
31+
*
32+
* @return throwing error handler
33+
*/
34+
@NotNull
35+
static GitCheckErrorHandler throwing() {
36+
return error -> {
37+
throw new GitCheckException(error.getMessage(), error.getCause());
38+
};
39+
}
40+
/**
41+
* Handles the error.
42+
*
43+
* @param error the error to handle
44+
*/
45+
void handle(@NotNull GitCheckError error);
46+
}

0 commit comments

Comments
 (0)