Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added a warning when a newer version is available in the cli. #1904

Merged
merged 5 commits into from
Aug 8, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions cli/src/main/java/de/jplag/cli/CLI.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ public CLI(String[] args) {
*/
public void executeCli() throws ExitException, IOException {
logger.debug("Your version of JPlag is {}", JPlag.JPLAG_VERSION);
JPlagVersionChecker.printVersionNotification();

if (!this.inputHandler.parse()) {
CollectedLogger.setLogLevel(this.inputHandler.getCliOptions().advanced.logLevel);
Expand Down
91 changes: 91 additions & 0 deletions cli/src/main/java/de/jplag/cli/JPlagVersionChecker.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package de.jplag.cli;

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLConnection;
import java.util.Optional;

import javax.json.Json;
import javax.json.JsonArray;
import javax.json.JsonObject;
import javax.json.JsonReader;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import de.jplag.JPlag;
import de.jplag.reporting.reportobject.model.Version;

/**
* Handles the check for newer versions.
*/
public class JPlagVersionChecker {
private static final String API_URL = "https://api.github.com/repos/jplag/JPlag/releases";
private static final Logger logger = LoggerFactory.getLogger(JPlagVersionChecker.class);
private static final String EXPECTED_VERSION_FORMAT = "v\\d\\.\\d\\.\\d+";
private static final String WARNING_UNABLE_TO_FETCH = "Unable to fetch version information. New version notification will not work.";
private static final String NEWER_VERSION_AVAILABLE = "There is a newer version ({}) available. You can fetch the newest version here: https://github.com/jplag/JPlag/releases.";
TwoOfTwelve marked this conversation as resolved.
Show resolved Hide resolved
TwoOfTwelve marked this conversation as resolved.
Show resolved Hide resolved
private static final String UNEXPECTED_ERROR = "There was an unexpected error, when checking for new versions. Please report this on: https://github.com/jplag/JPlag/issues";

private JPlagVersionChecker() {

}

/**
* Prints a warning if a newer version is available on GitHub.
*/
public static void printVersionNotification() {
Optional<Version> newerVersion = checkForNewVersion();
newerVersion.ifPresent(version -> logger.warn(NEWER_VERSION_AVAILABLE, version));
}

private static Optional<Version> checkForNewVersion() {
try {
JsonArray array = fetchApi();
Version newest = getNewestVersion(array);
Version current = JPlag.JPLAG_VERSION;

if (newest.compareTo(current) > 0) {
return Optional.of(newest);
}
} catch (IOException | URISyntaxException e) {
TwoOfTwelve marked this conversation as resolved.
Show resolved Hide resolved
logger.warn(WARNING_UNABLE_TO_FETCH);
} catch (Exception e) {
logger.error(UNEXPECTED_ERROR, e);
}

return Optional.empty();
}

private static JsonArray fetchApi() throws IOException, URISyntaxException {
URL url = new URI(API_URL).toURL();
URLConnection connection = url.openConnection();

try (JsonReader reader = Json.createReader(connection.getInputStream())) {
return reader.readArray();
}
}

private static Version getNewestVersion(JsonArray apiResult) {
return apiResult.stream().map(JsonObject.class::cast).map(version -> version.getString("name"))
.filter(versionName -> versionName.matches(EXPECTED_VERSION_FORMAT)).limit(1).map(JPlagVersionChecker::parseVersion).findFirst()
.orElse(JPlag.JPLAG_VERSION);
}

/**
* Parses the version name.
* @param versionName The version name. The expected format is: v[major].[minor].[patch]
* @return The parsed version
*/
private static Version parseVersion(String versionName) {
String withoutPrefix = versionName.substring(1);
TwoOfTwelve marked this conversation as resolved.
Show resolved Hide resolved
String[] parts = withoutPrefix.split("\\.");
return parseVersionParts(parts);
}

private static Version parseVersionParts(String[] parts) {
return new Version(Integer.parseInt(parts[0]), Integer.parseInt(parts[1]), Integer.parseInt(parts[2]));
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package de.jplag.reporting.reportobject.model;

import java.util.Comparator;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand All @@ -12,7 +14,8 @@
* @param minor MINOR version when you add functionality in a backwards compatible manner
* @param patch PATCH version when you make backwards compatible bug fixes
*/
public record Version(@JsonProperty("major") int major, @JsonProperty("minor") int minor, @JsonProperty("patch") int patch) {
public record Version(@JsonProperty("major") int major, @JsonProperty("minor") int minor, @JsonProperty("patch") int patch)
implements Comparable<Version> {

/**
* The default version for development (0.0.0).
Expand Down Expand Up @@ -42,4 +45,9 @@ public static Version parseVersion(String version) {
public String toString() {
return String.format("%d.%d.%d", major, minor, patch);
}

@Override
public int compareTo(Version other) {
return Comparator.comparing(Version::major).thenComparing(Version::minor).thenComparing(Version::patch).compare(this, other);
}
}