99
1010package org .elasticsearch .gradle .internal .transport ;
1111
12+ import org .elasticsearch .gradle .VersionProperties ;
13+ import org .elasticsearch .gradle .internal .transport .TransportVersionUtils .MajorMinor ;
1214import org .gradle .api .DefaultTask ;
1315import org .gradle .api .file .RegularFileProperty ;
1416import org .gradle .api .provider .ListProperty ;
1719import org .gradle .api .tasks .InputDirectory ;
1820import org .gradle .api .tasks .Optional ;
1921import org .gradle .api .tasks .TaskAction ;
22+ import org .gradle .api .tasks .options .Option ;
2023
2124import java .io .IOException ;
2225import java .nio .file .Path ;
2326import java .util .ArrayList ;
27+ import java .util .Collections ;
2428import java .util .Comparator ;
25- import java .util .HashSet ;
2629import java .util .List ;
2730import java .util .Objects ;
28- import java .util .function .Function ;
2931
30- import static org .elasticsearch .gradle .internal .transport .TransportVersionUtils .IdIncrement ;
32+ import static org .elasticsearch .gradle .internal .transport .TransportVersionUtils .IdIncrement .PATCH ;
33+ import static org .elasticsearch .gradle .internal .transport .TransportVersionUtils .IdIncrement .SERVER ;
3134import static org .elasticsearch .gradle .internal .transport .TransportVersionUtils .getDefinedFile ;
3235import static org .elasticsearch .gradle .internal .transport .TransportVersionUtils .getLatestId ;
3336import static org .elasticsearch .gradle .internal .transport .TransportVersionUtils .getPriorLatestId ;
@@ -56,16 +59,14 @@ public abstract class GenerateTransportVersionDataTask extends DefaultTask {
5659 *
5760 * @return
5861 */
59- @ Optional
6062 @ InputDirectory
61- public abstract RegularFileProperty getDataFileDirectory ();
63+ public abstract RegularFileProperty getDataFileDirectory (); // The plugin should always set this, not optional
6264
6365 /**
6466 * Used to set the name of the TransportVersionSet for which a data file will be generated.
6567 */
66- @ Optional
6768 @ Input
68- public abstract Property <String > getTVName ();
69+ public abstract Property <String > getTVName (); // The plugin should always set this, not optional
6970
7071 /**
7172 * Used to set the `major.minor` release version for which the specific TransportVersion ID will be generated.
@@ -75,52 +76,85 @@ public abstract class GenerateTransportVersionDataTask extends DefaultTask {
7576 @ Input
7677 public abstract ListProperty <String > getMinorVersionsForTV ();
7778
79+ // TODO can the Option annotation be on getMinorVersionsForTV() so that we don't have a separate getter?
7880 @ Optional
7981 @ Input
80- public abstract Property <Function <String , IdIncrement >> getIdIncrementSupplier ();
82+ @ Option (option = "versions" , description = "The minor version(s) for which to generate IDs, e.g. -Pversions=\" 9.2,9.1\" " )
83+ public abstract ListProperty <String > getMinorVersionsForTVCmdLine ();
84+
85+ // @Optional
86+ // @Input
87+ // public abstract Property<Function<String, IdIncrement>> getIdIncrementSupplier();
8188
8289 @ TaskAction
8390 public void generateTransportVersionData () throws IOException {
8491 final Path tvDataDir = Objects .requireNonNull (getDataFileDirectory ().getAsFile ().get ()).toPath ();
85- final var tvName = Objects .requireNonNull (getTVName ().get ());
86- final var forMinorVersions = Objects .requireNonNull (getMinorVersionsForTV ().get ());
87- final var idIncrementSupplier = Objects .requireNonNull (getIdIncrementSupplier ().get ());
92+ final String tvName = Objects .requireNonNull (getTVName ().get ());
93+ final var forMinorVersions = getMinorVersionsForTV ().getOrElse (
94+ Objects .requireNonNull (getMinorVersionsForTVCmdLine ().get ())
95+ );
96+ // final var idIncrementSupplier = Objects.requireNonNull(getIdIncrementSupplier().get());
8897
8998 // TODO
90- // - do we need to also validate that the minorVersions don't contain duplicates here? How do we enforce idempotency if we don't?
91- // - is there an order we need to apply? ( I don't think so)
92- // - Do we need to run this iteratively for backport construction, rather than accepting a list like this? (I don't think so)
93- // - also parse args if run alone
94- // - check that duplicate tags don't come in too
99+ // - [x] do we need to also validate that the minorVersions don't contain duplicates here? How do we enforce idempotency if we don't?
100+ // - is there an order we need to apply? ( I don't think so)
101+ // - Do we need to run this iteratively for backport construction, rather than accepting a list like this? (I don't think so)
102+ // - [x] parse args if run alone
103+ // - check that duplicate versions don't come in?
104+ // - Check that we don't have duplicate names (elsewhere, not here)
105+ // - Do we need to allow creating only patch versions?
106+ // - Must also keep data in sync for removal.
107+ // - We could remove any TVs not associated with a version arg. We then either generate or keep any tvs
108+ // for each version arg, and discard the rest
109+ // - How will this work for follow-up backport PRs that will not have all the version labels?
110+ // - The follow up PR somehow needs to know original IDs. Look at git? Need a new task?
111+ // -
95112
96113 // Load the tvSetData for the specified name, if it exists
97114 final var tvDefinition = getDefinedFile (tvDataDir , tvName );
98115 boolean tvDefinitionExists = tvDefinition != null ;
99- final List <Integer > definitionIds = tvDefinitionExists ? tvDefinition .ids () : List .of ();
116+ final List <Integer > preexistingIds = tvDefinitionExists ? Collections . unmodifiableList ( tvDefinition .ids () ) : List .of ();
100117
101- var seenIds = new HashSet <Integer >();
102- var ids = new ArrayList <>(definitionIds );
103- for (var forMinorVersion : forMinorVersions ) {
118+ List <Integer > ids = new ArrayList <>();
119+ for (var forVersion : forMinorVersions .stream ().map (MajorMinor ::of ).toList ()) {
104120 // Get the latest transport version data for the specified minor version.
105- final int latestTV = getLatestId (tvDataDir , forMinorVersion );
106-
107- // Create the new version
108- final int newVersion = idIncrementSupplier .apply (forMinorVersion ).bumpVersionNumber (latestTV );
109-
110- // Check that we don't already have an ID for this minor version
111- var priorLatestID = getPriorLatestId (tvDataDir , forMinorVersion );
112- if (containsValueInRange (priorLatestID , newVersion , ids )) {
121+ final int latestTV = getLatestId (tvDataDir , forVersion .toString ());
122+
123+ // Create the new version id
124+ // final int newID = idIncrementSupplier.apply(forVersion).bumpTransportVersion(latestTV);
125+ final int newID = incrementTVId (latestTV , forVersion );
126+
127+ // Check that if we already have a TV ID for this minor version
128+ Integer preexistingTVId = retrieveValueInRange (
129+ getPriorLatestId (tvDataDir , forVersion .toString ()),
130+ newID , preexistingIds
131+ );
132+ if (preexistingTVId != null ) {
133+ ids .add (preexistingTVId );
113134 // TODO: Should we log something here?
114- continue ;
135+ } else {
136+ ids .add (newID );
137+ // Update the LATEST file.
138+ // TODO need to revert the latest files for anything that has been removed.
139+ updateLatestFile (tvDataDir , forVersion .toString (), tvName , newID );
115140 }
116-
117- // Update the LATEST file.
118- updateLatestFile (tvDataDir , forMinorVersion , tvName , newVersion );
119141 }
120142
121143 writeDefinitionFile (tvDataDir , tvName , ids .stream ().sorted (Comparator .reverseOrder ()).toList ());
122144 }
123145
146+ private int incrementTVId (int tvID , MajorMinor version ) {
147+ // We can only run this task on main, so the ElasticsearchVersion will be for main.
148+ final var mainVersion = MajorMinor .of (VersionProperties .getElasticsearchVersion ());
149+ final var isMain = version .equals (mainVersion );
150+ if (isMain ) {
151+ return SERVER .bumpTransportVersion (tvID );
152+ } else {
153+ return PATCH .bumpTransportVersion (tvID );
154+ }
155+ // TODO add serverless check
156+ }
157+
124158 private boolean containsValueInRange (int lowerExclusive , int upperInclusive , List <Integer > ids ) {
125159 for (var id : ids ) {
126160 if (lowerExclusive < id && id <= upperInclusive ) {
@@ -129,4 +163,13 @@ private boolean containsValueInRange(int lowerExclusive, int upperInclusive, Lis
129163 }
130164 return false ;
131165 }
166+
167+ private Integer retrieveValueInRange (int lowerExclusive , int upperInclusive , List <Integer > ids ) {
168+ for (var id : ids ) {
169+ if (lowerExclusive < id && id <= upperInclusive ) {
170+ return id ;
171+ }
172+ }
173+ return null ;
174+ }
132175}
0 commit comments