Skip to content

Commit 8507e38

Browse files
committed
fix(semver): replace semver library with translation from node-semver
Translated from npm/node-semver@cb1ca1d. Translated SemVer, Range, Comparator, and their associated tests.
1 parent aaabe4a commit 8507e38

26 files changed

Lines changed: 2384 additions & 46 deletions

pom.xml

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<modelVersion>4.0.0</modelVersion>
55
<groupId>com.aws.greengrass</groupId>
66
<artifactId>component-common</artifactId>
7-
<version>2.1.1-SNAPSHOT</version>
7+
<version>2.2.0-SNAPSHOT</version>
88
<packaging>jar</packaging>
99

1010
<licenses>
@@ -31,11 +31,6 @@
3131
<artifactId>jackson-dataformat-yaml</artifactId>
3232
<version>2.13.2</version>
3333
</dependency>
34-
<dependency>
35-
<groupId>com.vdurmont</groupId>
36-
<artifactId>semver4j</artifactId>
37-
<version>3.1.0</version>
38-
</dependency>
3934
<dependency>
4035
<groupId>org.hamcrest</groupId>
4136
<artifactId>hamcrest</artifactId>
@@ -99,6 +94,7 @@
9994
<excludes>
10095
<exclude>*</exclude>
10196
<exclude>src/*/resources/**</exclude>
97+
<exclude>src/**/semver/**</exclude>
10298
</excludes>
10399
</licenseSet>
104100
</licenseSets>

src/main/java/com/amazon/aws/iot/greengrass/component/common/ComponentRecipe.java

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,20 @@
55

66
package com.amazon.aws.iot.greengrass.component.common;
77

8+
import com.amazon.aws.iot.greengrass.semver.SemVer;
89
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
910
import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder;
1011
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
11-
import com.vdurmont.semver4j.Semver;
12-
import java.util.Map;
13-
import java.util.regex.Matcher;
14-
import java.util.regex.Pattern;
1512
import lombok.Builder;
1613
import lombok.NonNull;
1714
import lombok.Value;
1815

1916
import java.util.Collections;
2017
import java.util.List;
18+
import java.util.Map;
2119
import java.util.Objects;
20+
import java.util.regex.Matcher;
21+
import java.util.regex.Pattern;
2222

2323
@JsonDeserialize(builder = ComponentRecipe.ComponentRecipeBuilder.class)
2424
@Value
@@ -37,7 +37,7 @@ public class ComponentRecipe {
3737

3838
@NonNull
3939
@JsonSerialize(using = SemverSerializer.class)
40-
Semver componentVersion;
40+
SemVer componentVersion;
4141

4242
@Builder.Default
4343
ComponentType componentType = ComponentType.GENERIC;
@@ -100,17 +100,17 @@ public ComponentRecipeBuilder componentName(String name) {
100100
}
101101
}
102102

103-
public ComponentRecipeBuilder componentVersion(Semver version) {
103+
public ComponentRecipeBuilder componentVersion(SemVer version) {
104104
if (version == null) {
105105
throw new NullPointerException("Component version is null");
106106
} else {
107107
if (version.getValue().length() > COMPONENT_VERSION_LENGTH) {
108108
throw new IllegalArgumentException(String.format("Component version length exceeds %d characters",
109109
COMPONENT_VERSION_LENGTH));
110110
}
111-
if (version.getMajor() > COMPONENT_MAX_VERSION_NUMBER
112-
|| version.getMinor() > COMPONENT_MAX_VERSION_NUMBER
113-
|| version.getPatch() > COMPONENT_MAX_VERSION_NUMBER) {
111+
if (version.major > COMPONENT_MAX_VERSION_NUMBER
112+
|| version.minor > COMPONENT_MAX_VERSION_NUMBER
113+
|| version.patch > COMPONENT_MAX_VERSION_NUMBER) {
114114
throw new IllegalArgumentException("Component version major, minor, patch can't exceed 6 digits");
115115
}
116116
this.componentVersion = version;

src/main/java/com/amazon/aws/iot/greengrass/component/common/DependencyProperties.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@
66
package com.amazon.aws.iot.greengrass.component.common;
77

88

9+
import com.amazon.aws.iot.greengrass.semver.Range;
910
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
1011
import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder;
1112
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
12-
import com.vdurmont.semver4j.Requirement;
1313
import lombok.Builder;
1414
import lombok.NonNull;
1515
import lombok.Value;
@@ -19,13 +19,13 @@
1919
public class DependencyProperties {
2020
@JsonSerialize(using = RequirementSerializer.class)
2121
@NonNull
22-
Requirement versionRequirement;
22+
Range versionRequirement;
2323

2424
DependencyType dependencyType;
2525

2626
@Builder
2727
public DependencyProperties(@NonNull String versionRequirement, DependencyType dependencyType) {
28-
this.versionRequirement = Requirement.buildNPM(versionRequirement);
28+
this.versionRequirement = new Range(versionRequirement);
2929
this.dependencyType = dependencyType == null ? DependencyType.HARD : dependencyType;
3030
}
3131

src/main/java/com/amazon/aws/iot/greengrass/component/common/RequirementSerializer.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,20 @@
55

66
package com.amazon.aws.iot.greengrass.component.common;
77

8+
import com.amazon.aws.iot.greengrass.semver.Range;
89
import com.fasterxml.jackson.core.JsonGenerator;
910
import com.fasterxml.jackson.databind.SerializerProvider;
1011
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
11-
import com.vdurmont.semver4j.Requirement;
1212

1313
import java.io.IOException;
1414

15-
public class RequirementSerializer extends StdSerializer<Requirement> {
15+
public class RequirementSerializer extends StdSerializer<Range> {
1616
public RequirementSerializer() {
17-
super(Requirement.class);
17+
super(Range.class);
1818
}
1919

2020
@Override
21-
public void serialize(final Requirement value, final JsonGenerator gen, final SerializerProvider provider) throws IOException {
21+
public void serialize(final Range value, final JsonGenerator gen, final SerializerProvider provider) throws IOException {
2222
final String version = value.toString();
2323
gen.writeString(version);
2424
}

src/main/java/com/amazon/aws/iot/greengrass/component/common/SemverSerializer.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,20 @@
55

66
package com.amazon.aws.iot.greengrass.component.common;
77

8+
import com.amazon.aws.iot.greengrass.semver.SemVer;
89
import com.fasterxml.jackson.core.JsonGenerator;
910
import com.fasterxml.jackson.databind.SerializerProvider;
1011
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
11-
import com.vdurmont.semver4j.Semver;
1212

1313
import java.io.IOException;
1414

15-
public class SemverSerializer extends StdSerializer<Semver> {
15+
public class SemverSerializer extends StdSerializer<SemVer> {
1616
public SemverSerializer() {
17-
super(Semver.class);
17+
super(SemVer.class);
1818
}
1919

2020
@Override
21-
public void serialize(final Semver value, final JsonGenerator gen, final SerializerProvider provider) throws IOException {
21+
public void serialize(final SemVer value, final JsonGenerator gen, final SerializerProvider provider) throws IOException {
2222
final String version = value.getValue();
2323
gen.writeString(version);
2424
}

src/main/java/com/amazon/aws/iot/greengrass/configuration/common/ComponentUpdate.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@
66
package com.amazon.aws.iot.greengrass.configuration.common;
77

88
import com.amazon.aws.iot.greengrass.component.common.SemverSerializer;
9+
import com.amazon.aws.iot.greengrass.semver.SemVer;
910
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
1011
import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder;
1112
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
12-
import com.vdurmont.semver4j.Semver;
1313
import lombok.AllArgsConstructor;
1414
import lombok.Builder;
1515
import lombok.Data;
@@ -24,7 +24,7 @@
2424
public class ComponentUpdate {
2525

2626
@JsonSerialize(using = SemverSerializer.class)
27-
private Semver version;
27+
private SemVer version;
2828

2929
private ConfigurationUpdate configurationUpdate;
3030

Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
/*
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*
5+
* Translated from node-semver:
6+
*
7+
* The ISC License
8+
* Copyright (c) Isaac Z. Schlueter and Contributors
9+
*
10+
* See com.amazon.aws.iot.greengrass.semver.THIRD-PARTY-LICENSE
11+
*/
12+
13+
package com.amazon.aws.iot.greengrass.semver;
14+
15+
import lombok.EqualsAndHashCode;
16+
17+
import java.util.Objects;
18+
import java.util.regex.Matcher;
19+
import java.util.regex.Pattern;
20+
21+
@EqualsAndHashCode
22+
public class Comparator {
23+
public final String value;
24+
private String operator;
25+
public SemVer semver;
26+
public static final AnySemVer ANY = Comparator.AnySemVer.ANY;
27+
28+
public Comparator(String comp) {
29+
this.parse(comp);
30+
31+
if (this.semver == ANY) {
32+
this.value = "";
33+
} else {
34+
this.value = this.operator + this.semver.getVersion();
35+
}
36+
}
37+
38+
private void parse (String comp) {
39+
Pattern r = SemVerRegexes.re.get(SemVerRegexes.t.get("COMPARATOR"));
40+
Matcher m = r.matcher(comp);
41+
42+
if (!m.find()) {
43+
throw new IllegalArgumentException("Invalid comparator " + comp);
44+
}
45+
46+
this.operator = m.group(1) != null ? m.group(1) : "";
47+
if (this.operator.equals("=")) {
48+
this.operator = "";
49+
}
50+
51+
// if it literally is just '>' or '' then allow anything.
52+
if (m.group(2) == null) {
53+
this.semver = ANY;
54+
} else {
55+
this.semver = new SemVer(m.group(2));
56+
}
57+
}
58+
59+
public boolean test (Object version) {
60+
if (this.semver == ANY || version == ANY) {
61+
return true;
62+
}
63+
64+
if (version instanceof String) {
65+
try {
66+
version = new SemVer((String) version);
67+
} catch (RuntimeException e) {
68+
return false;
69+
}
70+
}
71+
72+
return cmp((SemVer) version, this.operator, this.semver);
73+
}
74+
75+
public static boolean cmp(SemVer a, String op, SemVer b) {
76+
switch (op) {
77+
case "===":
78+
return a.getVersion().equals(b.getVersion());
79+
case "!==":
80+
return !a.getVersion().equals(b.getVersion());
81+
case "":
82+
case "=":
83+
case "==":
84+
return eq(a, b);
85+
case "!=":
86+
return neq(a, b);
87+
case ">":
88+
return gt(a, b);
89+
case ">=":
90+
return gte(a, b);
91+
case "<":
92+
return lt(a, b);
93+
case "<=":
94+
return lte(a, b);
95+
default:
96+
throw new IllegalArgumentException("Invalid operator " + op);
97+
}
98+
}
99+
100+
public static boolean eq(SemVer a, SemVer b){
101+
return a.compareTo(b) == 0;
102+
}
103+
104+
public static boolean neq(SemVer a, SemVer b){
105+
return a.compareTo(b) != 0;
106+
}
107+
108+
public static boolean gt(SemVer a, SemVer b){
109+
return a.compareTo(b) > 0;
110+
}
111+
112+
public static boolean gte(SemVer a, SemVer b){
113+
return a.compareTo(b) >= 0;
114+
}
115+
116+
public static boolean lt(SemVer a, SemVer b){
117+
return a.compareTo(b) < 0;
118+
}
119+
120+
public static boolean lte(SemVer a, SemVer b){
121+
return a.compareTo(b) <= 0;
122+
}
123+
124+
public boolean intersects (Comparator comp) {
125+
if (this.operator.equals("")) {
126+
if (this.value.equals("")) {
127+
return true;
128+
}
129+
return new Range(comp.value).test(this.semver);
130+
} else if (comp.operator.equals("")) {
131+
if (comp.value.equals("")) {
132+
return true;
133+
}
134+
return new Range(this.value).test(comp.semver);
135+
}
136+
137+
boolean sameDirectionIncreasing =
138+
(this.operator.equals(">=") || this.operator.equals(">")) &&
139+
(comp.operator.equals(">=") || comp.operator.equals(">"));
140+
boolean sameDirectionDecreasing =
141+
(this.operator.equals("<=") || this.operator.equals("<")) &&
142+
(comp.operator.equals("<=") || comp.operator.equals("<"));
143+
boolean sameSemVer = Objects.equals(this.semver.getVersion(), comp.semver.getVersion());
144+
boolean differentDirectionsInclusive =
145+
(this.operator.equals(">=") || this.operator.equals("<=")) &&
146+
(comp.operator.equals(">=") || comp.operator.equals("<="));
147+
boolean oppositeDirectionsLessThan =
148+
cmp(this.semver, "<", comp.semver) &&
149+
(Objects.equals(this.operator, ">=") || Objects.equals(this.operator, ">")) &&
150+
(Objects.equals(comp.operator, "<=") || Objects.equals(comp.operator, "<"));
151+
boolean oppositeDirectionsGreaterThan =
152+
cmp(this.semver, ">", comp.semver) &&
153+
(Objects.equals(this.operator, "<=") || Objects.equals(this.operator, "<")) &&
154+
(Objects.equals(comp.operator, ">=") || Objects.equals(comp.operator, ">"));
155+
156+
return (
157+
sameDirectionIncreasing ||
158+
sameDirectionDecreasing ||
159+
(sameSemVer && differentDirectionsInclusive) ||
160+
oppositeDirectionsLessThan ||
161+
oppositeDirectionsGreaterThan
162+
);
163+
}
164+
165+
@Override
166+
public String toString() {
167+
return this.value;
168+
}
169+
170+
public static class AnySemVer extends SemVer {
171+
final static AnySemVer ANY = new AnySemVer();
172+
private AnySemVer() {
173+
super("0.0.0");
174+
}
175+
}
176+
}
177+

0 commit comments

Comments
 (0)