Skip to content

Commit 688628b

Browse files
authored
Create a gradle task to extract version information for the new build release tag build infrastructure. (#104702)
Backport the extract versions task from #103627, along with the dummy tagVersions task from #104532
1 parent bc9e32b commit 688628b

File tree

4 files changed

+183
-0
lines changed

4 files changed

+183
-0
lines changed
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License
4+
* 2.0 and the Server Side Public License, v 1; you may not use this file except
5+
* in compliance with, at your election, the Elastic License 2.0 or the Server
6+
* Side Public License, v 1.
7+
*/
8+
9+
package org.elasticsearch.gradle.internal.release;
10+
11+
import com.github.javaparser.StaticJavaParser;
12+
import com.github.javaparser.ast.CompilationUnit;
13+
import com.github.javaparser.ast.body.FieldDeclaration;
14+
import com.github.javaparser.ast.expr.IntegerLiteralExpr;
15+
16+
import org.gradle.api.DefaultTask;
17+
import org.gradle.api.logging.Logger;
18+
import org.gradle.api.logging.Logging;
19+
import org.gradle.api.tasks.TaskAction;
20+
import org.gradle.api.tasks.options.Option;
21+
import org.gradle.initialization.layout.BuildLayout;
22+
23+
import java.io.IOException;
24+
import java.nio.file.Files;
25+
import java.nio.file.Path;
26+
import java.nio.file.StandardOpenOption;
27+
import java.util.ArrayList;
28+
import java.util.List;
29+
import java.util.function.Consumer;
30+
31+
import javax.inject.Inject;
32+
33+
public class ExtractCurrentVersionsTask extends DefaultTask {
34+
private static final Logger LOGGER = Logging.getLogger(ExtractCurrentVersionsTask.class);
35+
36+
static final String TRANSPORT_VERSION_TYPE = "TransportVersion";
37+
static final String INDEX_VERSION_TYPE = "IndexVersion";
38+
39+
static final String SERVER_MODULE_PATH = "server/src/main/java/";
40+
static final String TRANSPORT_VERSION_FILE_PATH = SERVER_MODULE_PATH + "org/elasticsearch/TransportVersions.java";
41+
static final String INDEX_VERSION_FILE_PATH = SERVER_MODULE_PATH + "org/elasticsearch/index/IndexVersions.java";
42+
43+
final Path rootDir;
44+
45+
private Path outputFile;
46+
47+
@Inject
48+
public ExtractCurrentVersionsTask(BuildLayout layout) {
49+
rootDir = layout.getRootDirectory().toPath();
50+
}
51+
52+
@Option(option = "output-file", description = "File to output tag information to")
53+
public void outputFile(String file) {
54+
this.outputFile = Path.of(file);
55+
}
56+
57+
@TaskAction
58+
public void executeTask() throws IOException {
59+
if (outputFile == null) {
60+
throw new IllegalArgumentException("Output file not specified");
61+
}
62+
63+
LOGGER.lifecycle("Extracting latest version information");
64+
65+
List<String> output = new ArrayList<>();
66+
int transportVersion = readLatestVersion(rootDir.resolve(TRANSPORT_VERSION_FILE_PATH));
67+
LOGGER.lifecycle("Transport version: {}", transportVersion);
68+
output.add(TRANSPORT_VERSION_TYPE + ":" + transportVersion);
69+
70+
int indexVersion = readLatestVersion(rootDir.resolve(INDEX_VERSION_FILE_PATH));
71+
LOGGER.lifecycle("Index version: {}", indexVersion);
72+
output.add(INDEX_VERSION_TYPE + ":" + indexVersion);
73+
74+
LOGGER.lifecycle("Writing version information to {}", outputFile);
75+
Files.write(outputFile, output, StandardOpenOption.CREATE, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING);
76+
}
77+
78+
static class FieldIdExtractor implements Consumer<FieldDeclaration> {
79+
private Integer highestVersionId;
80+
81+
Integer highestVersionId() {
82+
return highestVersionId;
83+
}
84+
85+
@Override
86+
public void accept(FieldDeclaration fieldDeclaration) {
87+
var ints = fieldDeclaration.findAll(IntegerLiteralExpr.class);
88+
switch (ints.size()) {
89+
case 0 -> {
90+
// No ints in the field declaration, ignore
91+
}
92+
case 1 -> {
93+
int id = ints.get(0).asNumber().intValue();
94+
if (highestVersionId != null && highestVersionId > id) {
95+
LOGGER.warn("Version ids [{}, {}] out of order", highestVersionId, id);
96+
} else {
97+
highestVersionId = id;
98+
}
99+
}
100+
default -> LOGGER.warn("Multiple integers found in version field declaration [{}]", fieldDeclaration); // and ignore it
101+
}
102+
}
103+
}
104+
105+
private static int readLatestVersion(Path javaVersionsFile) throws IOException {
106+
CompilationUnit java = StaticJavaParser.parse(javaVersionsFile);
107+
108+
FieldIdExtractor extractor = new FieldIdExtractor();
109+
java.walk(FieldDeclaration.class, extractor); // walks in code file order
110+
if (extractor.highestVersionId == null) {
111+
throw new IllegalArgumentException("No version ids found in " + javaVersionsFile);
112+
}
113+
return extractor.highestVersionId;
114+
}
115+
}

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@ public void apply(Project project) {
5050
project.getTasks()
5151
.register("updateVersions", UpdateVersionsTask.class, t -> project.getTasks().named("spotlessApply").get().mustRunAfter(t));
5252

53+
project.getTasks().register("extractCurrentVersions", ExtractCurrentVersionsTask.class);
54+
project.getTasks().register("tagVersions", TagVersionsTask.class); // no-op, nothing to tag
55+
5356
final FileTree yamlFiles = projectDirectory.dir("docs/changelog")
5457
.getAsFileTree()
5558
.matching(new PatternSet().include("**/*.yml", "**/*.yaml"));
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License
4+
* 2.0 and the Server Side Public License, v 1; you may not use this file except
5+
* in compliance with, at your election, the Elastic License 2.0 or the Server
6+
* Side Public License, v 1.
7+
*/
8+
9+
package org.elasticsearch.gradle.internal.release;
10+
11+
import org.gradle.api.DefaultTask;
12+
import org.gradle.api.tasks.options.Option;
13+
14+
import java.util.List;
15+
16+
/**
17+
* This is a no-op task that is only implemented for v8.13+
18+
*/
19+
public class TagVersionsTask extends DefaultTask {
20+
21+
@Option(option = "release", description = "Dummy option")
22+
public void release(String version) {}
23+
24+
@Option(option = "tag-version", description = "Dummy option")
25+
public void tagVersions(List<String> version) {}
26+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License
4+
* 2.0 and the Server Side Public License, v 1; you may not use this file except
5+
* in compliance with, at your election, the Elastic License 2.0 or the Server
6+
* Side Public License, v 1.
7+
*/
8+
9+
package org.elasticsearch.gradle.internal.release;
10+
11+
import com.github.javaparser.StaticJavaParser;
12+
import com.github.javaparser.ast.body.FieldDeclaration;
13+
14+
import org.elasticsearch.gradle.internal.release.ExtractCurrentVersionsTask.FieldIdExtractor;
15+
import org.junit.Test;
16+
17+
import static org.hamcrest.MatcherAssert.assertThat;
18+
import static org.hamcrest.Matchers.is;
19+
20+
public class ExtractCurrentVersionsTaskTests {
21+
22+
@Test
23+
public void testFieldExtractor() {
24+
var unit = StaticJavaParser.parse("""
25+
public class Version {
26+
public static final Version V_1 = def(1);
27+
public static final Version V_2 = def(2);
28+
public static final Version V_3 = def(3);
29+
30+
// ignore fields with no or more than one int
31+
public static final Version REF = V_3;
32+
public static final Version COMPUTED = compute(100, 200);
33+
}""");
34+
35+
FieldIdExtractor extractor = new FieldIdExtractor();
36+
unit.walk(FieldDeclaration.class, extractor);
37+
assertThat(extractor.highestVersionId(), is(3));
38+
}
39+
}

0 commit comments

Comments
 (0)