mirror of
https://github.com/HangarMC/Hangar.git
synced 2024-12-27 07:03:26 +08:00
Fix version formatting/make it depend on platform versions
This commit is contained in:
parent
4aaa87a096
commit
0d8341fe4f
@ -28,7 +28,6 @@ import java.lang.annotation.Annotation;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.info.GitProperties;
|
||||
@ -95,7 +94,7 @@ public class BackendDataController {
|
||||
final ArrayNode arrayNode = this.objectMapper.createArrayNode();
|
||||
for (final Platform platform : Platform.getValues()) {
|
||||
final ObjectNode objectNode = this.objectMapper.valueToTree(platform);
|
||||
objectNode.set("possibleVersions", this.objectMapper.valueToTree(this.platformService.getVersionsForPlatform(platform)));
|
||||
objectNode.set("possibleVersions", this.objectMapper.valueToTree(this.platformService.getDescendingVersionsForPlatform(platform)));
|
||||
arrayNode.add(objectNode);
|
||||
}
|
||||
return ResponseEntity.ok(arrayNode);
|
||||
|
@ -39,7 +39,7 @@ public class PlatformService extends HangarComponent {
|
||||
}
|
||||
|
||||
@Cacheable(CacheConfig.PLATFORMS)
|
||||
public List<PlatformVersion> getVersionsForPlatform(final Platform platform) {
|
||||
public List<PlatformVersion> getDescendingVersionsForPlatform(final Platform platform) {
|
||||
final List<String> versions = this.platformVersionDAO.getVersionsForPlatform(platform);
|
||||
final Map<String, List<String>> platformVersions = new LinkedHashMap<>();
|
||||
for (final String version : versions) {
|
||||
|
@ -22,7 +22,6 @@ import io.papermc.hangar.model.internal.logs.contexts.VersionContext;
|
||||
import io.papermc.hangar.model.internal.projects.HangarProject;
|
||||
import io.papermc.hangar.service.internal.PlatformService;
|
||||
import io.papermc.hangar.service.internal.projects.ProjectService;
|
||||
import io.papermc.hangar.util.StringUtils;
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumMap;
|
||||
import java.util.HashMap;
|
||||
@ -31,6 +30,7 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.SortedSet;
|
||||
import java.util.stream.Collectors;
|
||||
import io.papermc.hangar.util.VersionFormatter;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cache.annotation.CacheEvict;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
@ -65,7 +65,8 @@ public class VersionDependencyService extends HangarComponent {
|
||||
final Map<Platform, SortedSet<String>> platformDependencies = this.versionsApiDAO.getPlatformDependencies(versionId);
|
||||
final Map<Platform, String> platformDependenciesFormatted = new EnumMap<>(Platform.class);
|
||||
for (final Map.Entry<Platform, SortedSet<String>> entry : platformDependencies.entrySet()) {
|
||||
platformDependenciesFormatted.put(entry.getKey(), StringUtils.formatVersionNumbers(new ArrayList<>(entry.getValue())));
|
||||
final String formattedVersionRange = VersionFormatter.formatVersionRange(new ArrayList<>(entry.getValue()), this.platformService.getFullVersionsForPlatform(entry.getKey()));
|
||||
platformDependenciesFormatted.put(entry.getKey(), formattedVersionRange);
|
||||
}
|
||||
|
||||
// TODO into one query
|
||||
|
@ -1,12 +1,5 @@
|
||||
package io.papermc.hangar.util;
|
||||
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public final class StringUtils {
|
||||
|
||||
private StringUtils() {
|
||||
@ -31,109 +24,4 @@ public final class StringUtils {
|
||||
public static String compact(final String str) {
|
||||
return str.trim().replaceAll(" +", " ");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a version number split into an ordered list of numbers
|
||||
*
|
||||
* @param str version string to check (e.g. 2.3.1) MUST BE ALL NUMBERS
|
||||
* @return the list of integers in ltr order
|
||||
*/
|
||||
public static List<Integer> splitVersionNumber(final String str) {
|
||||
return Arrays.stream(str.split("\\.")).map(Integer::parseInt).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private static final Pattern LAST_WHOLE_VERSION = Pattern.compile("((?<=,\\s)|^)[0-9.]{2,}(?=-[0-9.]+$)");
|
||||
private static final Pattern PREV_HAS_HYPHEN = Pattern.compile("(?<=\\d-)[0-9.]+$");
|
||||
private static final Pattern PREV_HAS_COMMA_OR_FIRST = Pattern.compile("((?<=,\\s)|^)[0-9.]+$");
|
||||
|
||||
/**
|
||||
* Format a list of version numbers (will do sorting)
|
||||
*
|
||||
* @param versionNumbers version numbers
|
||||
* @return formatted string
|
||||
*/
|
||||
public static String formatVersionNumbers(final List<String> versionNumbers) {
|
||||
versionNumbers.sort((version1, version2) -> {
|
||||
int vnum1 = 0, vnum2 = 0;
|
||||
|
||||
for (int i = 0, j = 0; (i < version1.length() || j < version2.length()); ) {
|
||||
|
||||
while (i < version1.length() && version1.charAt(i) != '.') {
|
||||
vnum1 = vnum1 * 10 + (version1.charAt(i) - '0');
|
||||
i++;
|
||||
}
|
||||
|
||||
while (j < version2.length() && version2.charAt(j) != '.') {
|
||||
vnum2 = vnum2 * 10 + (version2.charAt(j) - '0');
|
||||
j++;
|
||||
}
|
||||
if (vnum1 > vnum2) {
|
||||
return 1;
|
||||
}
|
||||
if (vnum2 > vnum1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
vnum1 = vnum2 = 0;
|
||||
i++;
|
||||
j++;
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
|
||||
return versionNumbers.stream().reduce("", (verString, version) -> {
|
||||
if (verString.isBlank()) {
|
||||
return version;
|
||||
}
|
||||
final List<Integer> versionArr = splitVersionNumber(version);
|
||||
final Matcher hyphen = PREV_HAS_HYPHEN.matcher(verString);
|
||||
final Matcher comma = PREV_HAS_COMMA_OR_FIRST.matcher(verString);
|
||||
if (hyphen.find()) {
|
||||
final String[] group = hyphen.group().split("\\.");
|
||||
final int prevVersion = Integer.parseInt(group[group.length - 1]);
|
||||
final Matcher prevVersionMatcher = LAST_WHOLE_VERSION.matcher(verString);
|
||||
if (!prevVersionMatcher.find()) {
|
||||
throw new IllegalArgumentException("Bad version string");
|
||||
}
|
||||
final List<Integer> previousWholeVersion = splitVersionNumber(prevVersionMatcher.group());
|
||||
if (previousWholeVersion.size() == versionArr.size()) {
|
||||
if (versionArr.get(versionArr.size() - 1) - 1 == prevVersion) {
|
||||
return verString.replaceFirst("-[0-9.]+$", "-" + version);
|
||||
} else {
|
||||
return verString + ", " + version;
|
||||
}
|
||||
} else {
|
||||
return verString + ", " + version;
|
||||
}
|
||||
} else if (comma.find()) {
|
||||
final List<Integer> prevVersion = splitVersionNumber(comma.group());
|
||||
if (prevVersion.size() == versionArr.size()) {
|
||||
if (versionArr.get(versionArr.size() - 1) - 1 == prevVersion.get(prevVersion.size() - 1)) {
|
||||
return verString + "-" + version;
|
||||
} else {
|
||||
return verString + ", " + version;
|
||||
}
|
||||
} else {
|
||||
return verString + ", " + version;
|
||||
}
|
||||
} else {
|
||||
throw new IllegalArgumentException("bad formatting: " + version);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static String parsePythonNullable(final String input) {
|
||||
return input.equals("None") ? null : input;
|
||||
}
|
||||
|
||||
public static boolean isAnyEqualIgnoreCase(@NotNull final String lhs, final String @NotNull ... rhs) {
|
||||
|
||||
for (final String string : rhs) {
|
||||
if (lhs.equalsIgnoreCase(string)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,66 @@
|
||||
package io.papermc.hangar.util;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public final class VersionFormatter {
|
||||
|
||||
private VersionFormatter() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats a sorted version range string.
|
||||
*
|
||||
* @param versions list of versions to stringify
|
||||
* @param allVersions sorted list of all valid versions
|
||||
* @return formatted version range string
|
||||
* @throws IllegalArgumentException if versions contains a string not included in allVersions
|
||||
*/
|
||||
public static String formatVersionRange(final List<String> versions, final List<String> allVersions) {
|
||||
if (versions.isEmpty()) {
|
||||
return "";
|
||||
} else if (versions.size() == 1) {
|
||||
return versions.get(0);
|
||||
}
|
||||
|
||||
versions.sort((version1, version2) -> {
|
||||
final int index1 = allVersions.indexOf(version1);
|
||||
final int index2 = allVersions.indexOf(version2);
|
||||
if (index1 == -1) {
|
||||
throw new IllegalArgumentException("Version " + version1 + " not included in allVersions");
|
||||
} else if (index2 == -1) {
|
||||
throw new IllegalArgumentException("Version " + version2 + " not included in allVersions");
|
||||
}
|
||||
return index1 - index2;
|
||||
});
|
||||
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
String fromVersion = versions.get(0);
|
||||
String lastVersion = fromVersion;
|
||||
int lastVersionIndex = allVersions.indexOf(fromVersion);
|
||||
for (int i = 1; i < versions.size(); i++) {
|
||||
final String version = versions.get(i);
|
||||
final int versionIndex = allVersions.indexOf(version);
|
||||
if (versionIndex != lastVersionIndex + 1) {
|
||||
// Append last version/range if a new range starts
|
||||
if (!lastVersion.equals(fromVersion)) {
|
||||
builder.append(fromVersion).append('-').append(lastVersion);
|
||||
} else {
|
||||
builder.append(fromVersion);
|
||||
}
|
||||
|
||||
builder.append(", ");
|
||||
fromVersion = version;
|
||||
}
|
||||
|
||||
lastVersion = version;
|
||||
lastVersionIndex = versionIndex;
|
||||
}
|
||||
|
||||
// Append last version or range
|
||||
builder.append(fromVersion);
|
||||
if (!fromVersion.equals(lastVersion)) {
|
||||
builder.append('-').append(lastVersion);
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
@ -1,25 +1,24 @@
|
||||
package io.papermc.hangar.util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
class FormattedVersionsTest {
|
||||
private final List<String> versions = List.of("1.11", "1.11.1", "1.11.2", "1.11.3", "1.12", "1.13", "1.14", "1.14.1", "1.15", "1.15.1", "1.18");
|
||||
|
||||
@Test
|
||||
void testFormattedVersions() {
|
||||
final List<String> list1 = List.of("1.1", "1.2", "1.3", "1.5", "1.7", "1.8");
|
||||
this.testFormatVersionNumbers("1.11-1.11.2, 1.15-1.18", "1.11", "1.11.1", "1.11.2", "1.15", "1.15.1", "1.18");
|
||||
this.testFormatVersionNumbers("1.11-1.11.2, 1.15, 1.18", "1.11", "1.11.1", "1.11.2", "1.15", "1.18");
|
||||
this.testFormatVersionNumbers("1.11.1-1.11.2", "1.11.1", "1.11.2");
|
||||
this.testFormatVersionNumbers("1.11, 1.11.2, 1.15.1", "1.11", "1.11.2", "1.15.1");
|
||||
this.testFormatVersionNumbers("1.11, 1.12-1.13", "1.11", "1.12", "1.13");
|
||||
}
|
||||
|
||||
Assertions.assertEquals("1.1-1.3, 1.5, 1.7-1.8", StringUtils.formatVersionNumbers(new ArrayList<>(list1)));
|
||||
|
||||
final List<String> list2 = List.of("1.20", "1.23", "1.25", "1.30", "1.31");
|
||||
Assertions.assertEquals("1.20, 1.23, 1.25, 1.30-1.31", StringUtils.formatVersionNumbers(new ArrayList<>(list2)));
|
||||
|
||||
final List<String> list3 = List.of("1.1.0", "1.1.1", "1.2.0", "1.2.2", "1.3", "1.4");
|
||||
Assertions.assertEquals("1.1.0-1.1.1, 1.2.0, 1.2.2, 1.3-1.4", StringUtils.formatVersionNumbers(new ArrayList<>(list3)));
|
||||
|
||||
final List<String> list4 = List.of("1.1", "1.2", "1.3", "1.4", "1.5", "1.7", "1.8", "1.9", "1.10", "1.12");
|
||||
Assertions.assertEquals("1.1-1.5, 1.7-1.10, 1.12", StringUtils.formatVersionNumbers(new ArrayList<>(list4)));
|
||||
private void testFormatVersionNumbers(final String expected, final String... versions) {
|
||||
Assertions.assertEquals(expected, VersionFormatter.formatVersionRange(new ArrayList<>(List.of(versions)), this.versions));
|
||||
}
|
||||
}
|
||||
|
@ -1,24 +0,0 @@
|
||||
package io.papermc.hangar.util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
class StringUtilsTest {
|
||||
|
||||
@Test
|
||||
void testFormatVersionNumbers() {
|
||||
this.testFormatVersionNumbers("1.15-1.17", "1.15", "1.17", "1.16");
|
||||
this.testFormatVersionNumbers("1.15-1.17", "1.15", "1.17", "1.16");
|
||||
this.testFormatVersionNumbers("1.13, 1.15-1.17", "1.15", "1.17", "1.16", "1.13");
|
||||
this.testFormatVersionNumbers("1.13", "1.13");
|
||||
// this is a bit meh, but we have no reason to overthink this
|
||||
this.testFormatVersionNumbers("1.13, 1.15.2, 1.16, 1.17.0-1.17.1", "1.15.2", "1.17.1", "1.17.0", "1.16", "1.13");
|
||||
}
|
||||
|
||||
private void testFormatVersionNumbers(final String expected, final String... versions) {
|
||||
assertEquals(expected, StringUtils.formatVersionNumbers(new ArrayList<>(List.of(versions))));
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user