Skip to content

Commit

Permalink
filter for rc and snapshot in versions (#48)
Browse files Browse the repository at this point in the history
filter for rc and snapshot in versions
  • Loading branch information
FinlayRJW authored Oct 28, 2024
1 parent 5b0ae1e commit 2eecfcb
Show file tree
Hide file tree
Showing 5 changed files with 208 additions and 9 deletions.
5 changes: 5 additions & 0 deletions changelog/@unreleased/pr-48.v2.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
type: fix
fix:
description: filter for rc and snapshot in versions
links:
- https://github.com/palantir/gradle-consistent-versions-idea-plugin/pull/48
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,10 @@ interface Metadata {
@JacksonXmlElementWrapper(useWrapping = false)
@JacksonXmlProperty(localName = "versioning")
Versioning versioning();

static Builder builder() {
return new Builder();
}

class Builder extends ImmutableMetadata.Builder {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,21 @@
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.Lists;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Locale;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import org.immutables.value.Value;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
Expand All @@ -38,6 +45,9 @@
public class RepositoryExplorer {
private static final Logger log = LoggerFactory.getLogger(RepositoryExplorer.class);

private static final Pattern UNSTABLE_VERSION_PATTERN = Pattern.compile(
".*(-rc(-?\\d+)?|-SNAPSHOT|-M\\d+|-alpha(-?\\d+)?|-beta(-?\\d+)?)$", Pattern.CASE_INSENSITIVE);

private final Cache<CacheKey, Set<GroupPartOrPackageName>> folderCache = Caffeine.newBuilder()
.expireAfterWrite(10, TimeUnit.MINUTES)
.maximumSize(100)
Expand Down Expand Up @@ -104,21 +114,48 @@ private Set<GroupPartOrPackageName> fetchFoldersFromContent(String contents) {
}

private Set<DependencyVersion> parseVersionsFromContent(String content) {
Set<DependencyVersion> versions = new LinkedHashSet<>();
try {
XmlMapper xmlMapper = new XmlMapper();

Metadata metadata = xmlMapper.readValue(content, Metadata.class);
if (metadata.versioning() != null && metadata.versioning().versions() != null) {
String latest = metadata.versioning().latest();
for (String version : metadata.versioning().versions()) {
versions.add(DependencyVersion.of(version, latest.equals(version)));
}
}
return parseVersionsFromContent(metadata);
} catch (Exception e) {
log.error("Failed to parse maven-metadata.xml", e);
}
return versions;
return Collections.emptySet();
}

@VisibleForTesting
final Set<DependencyVersion> parseVersionsFromContent(Metadata metadata) {
List<String> allVersions = new ArrayList<>(metadata.versioning().versions());

if (allVersions.isEmpty()) {
return Collections.emptySet();
}

String releaseOrLatestVersion = Optional.ofNullable(
metadata.versioning().release())
.filter(l -> !l.isEmpty())
.orElseGet(() -> metadata.versioning().latest());

// Check if the releaseOrLatestVersion is stable, it not find first stable version, if no stable versions return
// the releaseOrLatestVersion
String latestStableVersion = Optional.of(releaseOrLatestVersion)
.filter(this::isStableVersion)
.or(() -> Lists.reverse(allVersions).stream()
.filter(this::isStableVersion)
.findFirst())
.orElse(releaseOrLatestVersion);

return allVersions.stream()
.map(version -> DependencyVersion.of(version, latestStableVersion.equals(version)))
.collect(Collectors.toCollection(LinkedHashSet::new));
}

private boolean isStableVersion(String version) {
return !UNSTABLE_VERSION_PATTERN
.matcher(version.toLowerCase(Locale.ROOT))
.matches();
}

@Value.Immutable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,11 @@
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import java.util.List;
import org.immutables.value.Value;

@Value.Immutable
@Value.Style(jdkOnly = true)
@JsonDeserialize(as = ImmutableVersioning.class)
@JsonSerialize(as = ImmutableVersioning.class)
@JsonIgnoreProperties(ignoreUnknown = true)
Expand All @@ -46,5 +48,11 @@ interface Versioning {
@Value.Parameter
@JacksonXmlElementWrapper(localName = "versions")
@JacksonXmlProperty(localName = "version")
String[] versions();
List<String> versions();

static Builder builder() {
return new Builder();
}

class Builder extends ImmutableVersioning.Builder {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
/*
* (c) Copyright 2024 Palantir Technologies Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.palantir.gradle.versions.intellij;

import static org.assertj.core.api.Assertions.assertThat;

import java.util.List;
import java.util.Set;
import org.junit.jupiter.api.Test;

public class RepositoryExplorerTests {

@Test
void test_gets_release_from_metadata() {
RepositoryExplorer repositoryExplorer = new RepositoryExplorer();

Versioning versioning = Versioning.builder()
.release("2.0.0")
.latest("1.0.0")
.versions(List.of("1.0.0", "2.0.0"))
.lastUpdated("unimportant")
.build();

Metadata metadata = Metadata.builder()
.groupId("com.example")
.artifactId("example-artifact")
.versioning(versioning)
.build();

Set<DependencyVersion> versions = repositoryExplorer.parseVersionsFromContent(metadata);

assertThat(versions).as("Check that versions set is not empty").isNotEmpty();

assertThat(versions)
.as("Check that versions set contains the release version marked as latest")
.anyMatch(v -> v.version().equals("2.0.0") && v.isLatest());
}

@Test
void test_gets_latest_from_metadata_if_release_missing() {
RepositoryExplorer repositoryExplorer = new RepositoryExplorer();

Versioning versioning = Versioning.builder()
.release("")
.latest("2.0.0")
.versions(List.of("1.0.0", "2.0.0"))
.lastUpdated("unimportant")
.build();

Metadata metadata = Metadata.builder()
.groupId("com.example")
.artifactId("example-artifact")
.versioning(versioning)
.build();

Set<DependencyVersion> versions = repositoryExplorer.parseVersionsFromContent(metadata);

assertThat(versions).as("Check that versions set is not empty").isNotEmpty();

assertThat(versions)
.as("Check that versions set contains the latest version marked as latest")
.anyMatch(v -> v.version().equals("2.0.0") && v.isLatest());
}

@Test
void test_unstable_versions_are_skipped() {
RepositoryExplorer repositoryExplorer = new RepositoryExplorer();

Versioning versioning = Versioning.builder()
.release("2.1.0-SNAPSHOT")
.latest("2.1.0-SNAPSHOT")
.versions(List.of(
"1.0.0",
"2.0.0",
"2.1.0-rc",
"2.1.0-rc1",
"2.1.0-rc-2",
"2.1.0-M2",
"2.1.0-alpha",
"2.1.0-alpha2",
"2.1.0-alpha-3",
"2.1.0-beta",
"2.1.0-beta-2",
"2.1.0-beta3",
"2.1.0-SNAPSHOT"))
.lastUpdated("unimportant")
.build();

Metadata metadata = Metadata.builder()
.groupId("com.example")
.artifactId("example-artifact")
.versioning(versioning)
.build();

Set<DependencyVersion> versions = repositoryExplorer.parseVersionsFromContent(metadata);

assertThat(versions).as("Check that versions set is not empty").isNotEmpty();

assertThat(versions)
.as("Check that regex rejects all unstable versions")
.anyMatch(v -> v.version().equals("2.0.0") && v.isLatest());
}

@Test
void test_rc_in_name_is_matched() {
RepositoryExplorer repositoryExplorer = new RepositoryExplorer();

Versioning versioning = Versioning.builder()
.release("2.1.0-SNAPSHOT")
.latest("2.1.0-SNAPSHOT")
.versions(List.of("1.0.0", "rc-2.0.0", "2.1.0-SNAPSHOT"))
.lastUpdated("unimportant")
.build();

Metadata metadata = Metadata.builder()
.groupId("com.example")
.artifactId("example-artifact")
.versioning(versioning)
.build();

Set<DependencyVersion> versions = repositoryExplorer.parseVersionsFromContent(metadata);

assertThat(versions).as("Check that versions set is not empty").isNotEmpty();

assertThat(versions)
.as("Check that rc can be used in a version name")
.anyMatch(v -> v.version().equals("rc-2.0.0") && v.isLatest());
}
}

0 comments on commit 2eecfcb

Please sign in to comment.