Skip to content

Commit a6fc27e

Browse files
authored
Add release tooling for adding new transport versions (#122426) (#122448)
1 parent 32285b1 commit a6fc27e

File tree

2 files changed

+184
-2
lines changed

2 files changed

+184
-2
lines changed

build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/release/UpdateVersionsTask.java

Lines changed: 94 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
1616
import com.github.javaparser.ast.body.FieldDeclaration;
1717
import com.github.javaparser.ast.body.VariableDeclarator;
18+
import com.github.javaparser.ast.expr.Expression;
1819
import com.github.javaparser.ast.expr.NameExpr;
1920
import com.github.javaparser.printer.lexicalpreservation.LexicalPreservingPrinter;
2021
import com.google.common.annotations.VisibleForTesting;
@@ -33,6 +34,7 @@
3334
import java.util.Objects;
3435
import java.util.Optional;
3536
import java.util.TreeMap;
37+
import java.util.function.Function;
3638
import java.util.regex.Matcher;
3739
import java.util.regex.Pattern;
3840
import java.util.stream.Collectors;
@@ -51,6 +53,8 @@ public class UpdateVersionsTask extends AbstractVersionsTask {
5153
private boolean setCurrent;
5254
@Nullable
5355
private Version removeVersion;
56+
@Nullable
57+
private String addTransportVersion;
5458

5559
@Inject
5660
public UpdateVersionsTask(BuildLayout layout) {
@@ -62,6 +66,11 @@ public void addVersion(String version) {
6266
this.addVersion = Version.fromString(version);
6367
}
6468

69+
@Option(option = "add-transport-version", description = "Specifies transport version to add")
70+
public void addTransportVersion(String transportVersion) {
71+
this.addTransportVersion = transportVersion;
72+
}
73+
6574
@Option(option = "set-current", description = "Set the 'current' constant to the new version")
6675
public void setCurrent(boolean setCurrent) {
6776
this.setCurrent = setCurrent;
@@ -87,15 +96,18 @@ static Optional<Version> parseVersionField(CharSequence field) {
8796

8897
@TaskAction
8998
public void executeTask() throws IOException {
90-
if (addVersion == null && removeVersion == null) {
99+
if (addVersion == null && removeVersion == null && addTransportVersion == null) {
91100
throw new IllegalArgumentException("No versions to add or remove specified");
92101
}
93102
if (setCurrent && addVersion == null) {
94103
throw new IllegalArgumentException("No new version added to set as the current version");
95104
}
96-
if (Objects.equals(addVersion, removeVersion)) {
105+
if (addVersion != null && removeVersion != null && Objects.equals(addVersion, removeVersion)) {
97106
throw new IllegalArgumentException("Same version specified to add and remove");
98107
}
108+
if (addTransportVersion != null && addTransportVersion.split(":").length != 2) {
109+
throw new IllegalArgumentException("Transport version specified must be in the format '<constant>:<version-id>'");
110+
}
99111

100112
Path versionJava = rootDir.resolve(VERSION_FILE_PATH);
101113
CompilationUnit file = LexicalPreservingPrinter.setup(StaticJavaParser.parse(versionJava));
@@ -115,6 +127,18 @@ public void executeTask() throws IOException {
115127
modifiedFile = removed;
116128
}
117129
}
130+
if (addTransportVersion != null) {
131+
var constant = addTransportVersion.split(":")[0];
132+
var versionId = Integer.parseInt(addTransportVersion.split(":")[1]);
133+
LOGGER.lifecycle("Adding transport version constant [{}] with id [{}]", constant, versionId);
134+
135+
var transportVersionsFile = rootDir.resolve(TRANSPORT_VERSIONS_FILE_PATH);
136+
var transportVersions = LexicalPreservingPrinter.setup(StaticJavaParser.parse(transportVersionsFile));
137+
var modified = addTransportVersionConstant(transportVersions, constant, versionId);
138+
if (modified.isPresent()) {
139+
writeOutNewContents(transportVersionsFile, modified.get());
140+
}
141+
}
118142

119143
if (modifiedFile.isPresent()) {
120144
writeOutNewContents(versionJava, modifiedFile.get());
@@ -161,6 +185,51 @@ static Optional<CompilationUnit> addVersionConstant(CompilationUnit versionJava,
161185
return Optional.of(versionJava);
162186
}
163187

188+
@VisibleForTesting
189+
static Optional<CompilationUnit> addTransportVersionConstant(CompilationUnit transportVersions, String constant, int versionId) {
190+
ClassOrInterfaceDeclaration transportVersionsClass = transportVersions.getClassByName("TransportVersions").get();
191+
if (transportVersionsClass.getFieldByName(constant).isPresent()) {
192+
LOGGER.lifecycle("New transport version constant [{}] already present, skipping", constant);
193+
return Optional.empty();
194+
}
195+
196+
TreeMap<Integer, FieldDeclaration> versions = transportVersionsClass.getFields()
197+
.stream()
198+
.filter(f -> f.getElementType().asString().equals("TransportVersion"))
199+
.filter(
200+
f -> f.getVariables().stream().limit(1).allMatch(v -> v.getInitializer().filter(Expression::isMethodCallExpr).isPresent())
201+
)
202+
.filter(f -> f.getVariable(0).getInitializer().get().asMethodCallExpr().getNameAsString().endsWith("def"))
203+
.collect(
204+
Collectors.toMap(
205+
f -> f.getVariable(0)
206+
.getInitializer()
207+
.get()
208+
.asMethodCallExpr()
209+
.getArgument(0)
210+
.asIntegerLiteralExpr()
211+
.asNumber()
212+
.intValue(),
213+
Function.identity(),
214+
(f1, f2) -> {
215+
throw new IllegalStateException("Duplicate version constant " + f1);
216+
},
217+
TreeMap::new
218+
)
219+
);
220+
221+
// find the version this should be inserted after
222+
Map.Entry<Integer, FieldDeclaration> previousVersion = versions.lowerEntry(versionId);
223+
if (previousVersion == null) {
224+
throw new IllegalStateException(String.format("Could not find previous version to [%s]", versionId));
225+
}
226+
227+
FieldDeclaration newTransportVersion = createNewTransportVersionConstant(previousVersion.getValue(), constant, versionId);
228+
transportVersionsClass.getMembers().addAfter(newTransportVersion, previousVersion.getValue());
229+
230+
return Optional.of(transportVersions);
231+
}
232+
164233
private static FieldDeclaration createNewVersionConstant(FieldDeclaration lastVersion, String newName, String newExpr) {
165234
return new FieldDeclaration(
166235
new NodeList<>(lastVersion.getModifiers()),
@@ -172,6 +241,29 @@ private static FieldDeclaration createNewVersionConstant(FieldDeclaration lastVe
172241
);
173242
}
174243

244+
private static FieldDeclaration createNewTransportVersionConstant(FieldDeclaration lastVersion, String newName, int newId) {
245+
return new FieldDeclaration(
246+
new NodeList<>(lastVersion.getModifiers()),
247+
new VariableDeclarator(
248+
lastVersion.getCommonType(),
249+
newName,
250+
StaticJavaParser.parseExpression(String.format("def(%s)", formatTransportVersionId(newId)))
251+
)
252+
);
253+
}
254+
255+
private static String formatTransportVersionId(int id) {
256+
String idString = Integer.toString(id);
257+
258+
return new StringBuilder(idString.substring(idString.length() - 2, idString.length())).insert(0, "_")
259+
.insert(0, idString.substring(idString.length() - 3, idString.length() - 2))
260+
.insert(0, "_")
261+
.insert(0, idString.substring(idString.length() - 6, idString.length() - 3))
262+
.insert(0, "_")
263+
.insert(0, idString.substring(0, idString.length() - 6))
264+
.toString();
265+
}
266+
175267
@VisibleForTesting
176268
static Optional<CompilationUnit> removeVersionConstant(CompilationUnit versionJava, Version version) {
177269
String removeFieldName = toVersionField(version);

build-tools-internal/src/test/java/org/elasticsearch/gradle/internal/release/UpdateVersionsTaskTests.java

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,96 @@ public void updateVersionFile_removesCorrectly() throws Exception {
239239
assertThat(field.isPresent(), is(false));
240240
}
241241

242+
@Test
243+
public void addTransportVersion() throws Exception {
244+
var transportVersions = """
245+
public class TransportVersions {
246+
public static final TransportVersion V_1_0_0 = def(1_000_0_00);
247+
public static final TransportVersion V_1_1_0 = def(1_001_0_00);
248+
public static final TransportVersion V_1_2_0 = def(1_002_0_00);
249+
public static final TransportVersion V_1_2_1 = def(1_002_0_01);
250+
public static final TransportVersion V_1_2_2 = def(1_002_0_02);
251+
public static final TransportVersion SOME_OTHER_VERSION = def(1_003_0_00);
252+
public static final TransportVersion YET_ANOTHER_VERSION = def(1_004_0_00);
253+
public static final TransportVersion MINIMUM_COMPATIBLE = V_1_0_0;
254+
}
255+
""";
256+
257+
var expectedTransportVersions = """
258+
public class TransportVersions {
259+
260+
public static final TransportVersion V_1_0_0 = def(1_000_0_00);
261+
262+
public static final TransportVersion V_1_1_0 = def(1_001_0_00);
263+
264+
public static final TransportVersion V_1_2_0 = def(1_002_0_00);
265+
266+
public static final TransportVersion V_1_2_1 = def(1_002_0_01);
267+
268+
public static final TransportVersion V_1_2_2 = def(1_002_0_02);
269+
270+
public static final TransportVersion SOME_OTHER_VERSION = def(1_003_0_00);
271+
272+
public static final TransportVersion YET_ANOTHER_VERSION = def(1_004_0_00);
273+
274+
public static final TransportVersion NEXT_TRANSPORT_VERSION = def(1_005_0_00);
275+
276+
public static final TransportVersion MINIMUM_COMPATIBLE = V_1_0_0;
277+
}
278+
""";
279+
280+
var unit = StaticJavaParser.parse(transportVersions);
281+
var result = UpdateVersionsTask.addTransportVersionConstant(unit, "NEXT_TRANSPORT_VERSION", 1_005_0_00);
282+
283+
assertThat(result.isPresent(), is(true));
284+
assertThat(result.get(), hasToString(expectedTransportVersions));
285+
}
286+
287+
@Test
288+
public void addTransportVersionPatch() throws Exception {
289+
var transportVersions = """
290+
public class TransportVersions {
291+
public static final TransportVersion V_1_0_0 = def(1_000_0_00);
292+
public static final TransportVersion V_1_1_0 = def(1_001_0_00);
293+
public static final TransportVersion V_1_2_0 = def(1_002_0_00);
294+
public static final TransportVersion V_1_2_1 = def(1_002_0_01);
295+
public static final TransportVersion V_1_2_2 = def(1_002_0_02);
296+
public static final TransportVersion SOME_OTHER_VERSION = def(1_003_0_00);
297+
public static final TransportVersion YET_ANOTHER_VERSION = def(1_004_0_00);
298+
public static final TransportVersion MINIMUM_COMPATIBLE = V_1_0_0;
299+
}
300+
""";
301+
302+
var expectedTransportVersions = """
303+
public class TransportVersions {
304+
305+
public static final TransportVersion V_1_0_0 = def(1_000_0_00);
306+
307+
public static final TransportVersion V_1_1_0 = def(1_001_0_00);
308+
309+
public static final TransportVersion V_1_2_0 = def(1_002_0_00);
310+
311+
public static final TransportVersion V_1_2_1 = def(1_002_0_01);
312+
313+
public static final TransportVersion V_1_2_2 = def(1_002_0_02);
314+
315+
public static final TransportVersion SOME_OTHER_VERSION = def(1_003_0_00);
316+
317+
public static final TransportVersion PATCH_TRANSPORT_VERSION = def(1_003_0_01);
318+
319+
public static final TransportVersion YET_ANOTHER_VERSION = def(1_004_0_00);
320+
321+
public static final TransportVersion MINIMUM_COMPATIBLE = V_1_0_0;
322+
}
323+
""";
324+
325+
var unit = StaticJavaParser.parse(transportVersions);
326+
var result = UpdateVersionsTask.addTransportVersionConstant(unit, "PATCH_TRANSPORT_VERSION", 1_003_0_01);
327+
328+
assertThat(result.isPresent(), is(true));
329+
assertThat(result.get(), hasToString(expectedTransportVersions));
330+
}
331+
242332
private static Optional<FieldDeclaration> findFirstField(Node node, String name) {
243333
return node.findFirst(FieldDeclaration.class, f -> f.getVariable(0).getName().getIdentifier().equals(name));
244334
}

0 commit comments

Comments
 (0)