Skip to content

Commit

Permalink
feat: Adding possibility to invert vers ref: #171
Browse files Browse the repository at this point in the history
  • Loading branch information
RingoDev committed Feb 22, 2025
1 parent a17d55b commit 36f29d4
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,22 @@ boolean matches(final Version version) {
};
}

/**
* Inverts the comparator of the constraint e.g. < 1.3 becomes >= 1.3
* @return a new inverted constraint and null if current comparator is a wildcard: *
*/
Constraint invert(){
return switch (comparator) {
case LESS_THAN -> new Constraint(scheme, Comparator.GREATER_THAN_OR_EQUAL, version);
case LESS_THAN_OR_EQUAL -> new Constraint(scheme, Comparator.GREATER_THAN, version);
case GREATER_THAN_OR_EQUAL -> new Constraint(scheme, Comparator.LESS_THAN, version);
case GREATER_THAN -> new Constraint(scheme, Comparator.LESS_THAN_OR_EQUAL, version);
case EQUAL -> new Constraint(scheme, Comparator.NOT_EQUAL, version);
case NOT_EQUAL -> new Constraint(scheme, Comparator.EQUAL, version);
case WILDCARD -> null;
};
}

private static String maybeUrlDecode(final String version) {
if (version.contains("%")) {
return URLDecoder.decode(version, StandardCharsets.UTF_8);
Expand Down
13 changes: 13 additions & 0 deletions versatile-core/src/main/java/io/github/nscuro/versatile/Vers.java
Original file line number Diff line number Diff line change
Expand Up @@ -499,6 +499,19 @@ public boolean overlapsWith(Vers vers) {
return false;
}

/**
* Inverts a given vers expression and returns a new simplified vers
*
* @throws VersException if the vers is a wildcard
*/
public Vers invert() {
if (isWildcard()) {
throw new VersException("Can not invert wildcard vers");
}
var inverted = constraints.stream().map(Constraint::invert).toList();
return new Vers(this.scheme(), inverted).simplify();
}

@Override
public String toString() {
final String schemeStr = scheme().toLowerCase();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatNoException;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.junit.jupiter.params.provider.Arguments.arguments;

class VersTest {
Expand Down Expand Up @@ -221,4 +222,76 @@ void testHasOverlap(String version1, String version2, boolean expected) {
assertThat(v1.overlapsWith(v2)).isEqualTo(expected);
assertThat(v2.overlapsWith(v1)).isEqualTo(expected);
}


@ParameterizedTest
@CsvSource({
"'vers:generic/1.2.3', 'vers:generic/!=1.2.3'",
"'vers:generic/>=1.2.0|<2.0.0', 'vers:generic/<1.2.0|>=2.0.0'",
"'vers:generic/<1.2.0', 'vers:generic/>=1.2.0'",
"'vers:generic/>=1.0.0|<3.0.0', 'vers:generic/<1.0.0|>=3.0.0'",
"'vers:generic/1.0.0|2.0.0', 'vers:generic/!=1.0.0|!=2.0.0'",
"'vers:generic/<2.0.0', 'vers:generic/>=2.0.0'",
"'vers:generic/>=1.0.0|<3.0.0', 'vers:generic/<1.0.0|>=3.0.0'",
"'vers:generic/1.0.0|1.1.0', 'vers:generic/!=1.0.0|!=1.1.0'",
"'vers:generic/<1.0.0|>=3.0.0', 'vers:generic/>=1.0.0|<3.0.0'",
"'vers:generic/>=1.0.0|<2.5.0|>=3.0.0|<4.0.0', 'vers:generic/<1.0.0|>=2.5.0|<3.0.0|>=4.0.0'",
"'vers:generic/<1.0.0|>=2.0.0|<2.5.0', 'vers:generic/>=1.0.0|<2.0.0|>=2.5.0'",
"'vers:generic/<3.0.0|>=1.0.0', 'vers:generic/<1.0.0|>=3.0.0'",
"'vers:generic/1.0.0|1.2.0|1.4.0', 'vers:generic/!=1.0.0|!=1.2.0|!=1.4.0'",
"'vers:generic/>=1.0.0|<5.0.0', 'vers:generic/<1.0.0|>=5.0.0'",
"'vers:generic/>=1.0.0|<2.0.0', 'vers:generic/<1.0.0|>=2.0.0'",
"'vers:generic/>1.2.3', 'vers:generic/<=1.2.3'",
"'vers:generic/>1.2.3|<1.2.9', 'vers:generic/<=1.2.3|>=1.2.9'",
"'vers:generic/>1.2.3|<1.3.1', 'vers:generic/<=1.2.3|>=1.3.1'",
"'vers:generic/>=1.0.0|<2.0.0|>=2.5.0|<3.5.0', 'vers:generic/<1.0.0|>=2.0.0|<2.5.0|>=3.5.0'",
"'vers:generic/<1.5.0|>=2.0.0|!=2.7.0|<3.2.0', 'vers:generic/>=1.5.0|<2.0.0|2.7.0|>=3.2.0'",
"'vers:generic/>=1.0.0|!=1.5.0|<2.5.0|>=3.0.0|!=3.2.0', 'vers:generic/<1.0.0|1.5.0|>=2.5.0|<3.0.0|3.2.0'",
"'vers:generic/>1.2.3|!=2.0.0|<=3.5.1|3.6.2|>4.0.0|<5.0.0', 'vers:generic/<=1.2.3|2.0.0|>3.5.1|!=3.6.2|<=4.0.0|>=5.0.0'",
"'vers:generic/>=1.1.0|<2.2.0|!=2.1.0|>=3.0.0|<4.0.0', 'vers:generic/<1.1.0|>=2.2.0|<3.0.0|>=4.0.0'"
})
void testInvert(String version, String expectedInverted) {
var v = Vers.parse(version);
var inverted = v.invert();
assertThat(inverted.toString()).isEqualTo(expectedInverted);
}

@ParameterizedTest
@CsvSource({
"'vers:generic/1.2.3'",
"'vers:generic/>=1.2.0|<2.0.0'",
"'vers:generic/<1.2.0'",
"'vers:generic/>=1.0.0|<3.0.0'",
"'vers:generic/1.0.0|2.0.0'",
"'vers:generic/<2.0.0'",
"'vers:generic/>=1.0.0|<3.0.0'",
"'vers:generic/1.0.0|1.1.0'",
"'vers:generic/<1.0.0|>=3.0.0'",
"'vers:generic/>=1.0.0|<2.5.0|>=3.0.0|<4.0.0'",
"'vers:generic/<1.0.0|>=2.0.0|<2.5.0'",
"'vers:generic/>=1.0.0|<3.0.0'",
"'vers:generic/1.0.0|1.2.0|1.4.0'",
"'vers:generic/>=1.0.0|<5.0.0'",
"'vers:generic/>=1.0.0|<2.0.0'",
"'vers:generic/>1.2.3'",
"'vers:generic/>1.2.3|<1.2.9'",
"'vers:generic/>1.2.3|<1.3.1'",
"'vers:generic/>=1.0.0|<2.0.0|>=2.5.0|<3.5.0'",
"'vers:generic/<1.5.0|>=2.0.0|!=2.7.0|<3.2.0'",
"'vers:generic/>=1.0.0|!=1.5.0|<2.5.0|>=3.0.0|!=3.2.0'",
"'vers:generic/>1.2.3|!=2.0.0|<=3.5.1|>4.0.0|<5.0.0'",
"'vers:generic/>=1.1.0|<2.2.0|!=2.1.0|>=3.0.0|<4.0.0'"
})
void testInvertedDoesNotOverlap(String version) {
var v = Vers.parse(version);
var inverted = v.invert();
assertThat(v.overlapsWith(inverted)).isEqualTo(false);
}

@Test
void testInvertThrowsErrorOnWildcard() {
var v = Vers.parse("vers:generic/*");
assertThatThrownBy(v::invert)
.isInstanceOf(VersException.class);
}
}

0 comments on commit 36f29d4

Please sign in to comment.