6
6
import com .fasterxml .jackson .core .util .DefaultPrettyPrinter ;
7
7
import com .fasterxml .jackson .databind .ObjectMapper ;
8
8
import com .fasterxml .jackson .databind .SerializationFeature ;
9
+ import org .graalvm .internal .tck .exceptions .ContributingException ;
9
10
import org .graalvm .internal .tck .model .MetadataIndexEntry ;
10
11
import org .graalvm .internal .tck .model .contributing .Question ;
11
12
import org .graalvm .internal .tck .utils .ConfigurationStringBuilder ;
25
26
import java .nio .file .Files ;
26
27
import java .nio .file .Path ;
27
28
import java .nio .file .StandardOpenOption ;
28
- import java .util .*;
29
+ import java .util .ArrayList ;
30
+ import java .util .Arrays ;
31
+ import java .util .Comparator ;
32
+ import java .util .HashMap ;
33
+ import java .util .HashSet ;
34
+ import java .util .List ;
35
+ import java .util .Map ;
36
+ import java .util .Optional ;
37
+ import java .util .Set ;
29
38
30
39
public abstract class ContributionTask extends DefaultTask {
40
+ private static final String BRANCH_NAME_PREFIX = "add-support-for-" ;
31
41
private static final String METADATA_INDEX = "metadata/index.json" ;
32
42
private static final String BUILD_FILE = "build.gradle" ;
33
43
private static final String USER_CODE_FILTER_FILE = "user-code-filter.json" ;
@@ -52,16 +62,16 @@ private record ContributingQuestion(String question, String help) {}
52
62
private final Map <String , ContributingQuestion > questions = new HashMap <>();
53
63
54
64
private void initializeWorkingDirectories (){
55
- testsDirectory = Path . of ( getProject ().file (CoordinateUtils .replace ("tests/src/$group$/$artifact$/$version$" , coordinates )).getAbsolutePath () );
56
- metadataDirectory = Path . of ( getProject ().file (CoordinateUtils .replace ("metadata/$group$/$artifact$/$version$" , coordinates )).getAbsolutePath () );
57
- this . gradlew = Path .of (getProject ().file ("gradlew" ).getAbsolutePath ());
65
+ testsDirectory = getProject ().file (CoordinateUtils .replace ("tests/src/$group$/$artifact$/$version$" , coordinates )).toPath ( );
66
+ metadataDirectory = getProject ().file (CoordinateUtils .replace ("metadata/$group$/$artifact$/$version$" , coordinates )).toPath ( );
67
+ gradlew = Path .of (getProject ().file ("gradlew" ).getAbsolutePath ());
58
68
}
59
69
60
70
private void loadQuestions () throws IOException {
61
71
File questionsJson = getProject ().file ("tests/tck-build-logic/src/main/resources/contributing/questions.json" );
62
72
List <Question > contributingQuestions = objectMapper .readValue (questionsJson , new TypeReference <>() {});
63
73
for (var question : contributingQuestions ) {
64
- this . questions .put (question .questionKey (), new ContributingQuestion (question .question (), question .help ()));
74
+ questions .put (question .questionKey (), new ContributingQuestion (question .question (), question .help ()));
65
75
}
66
76
}
67
77
@@ -72,7 +82,7 @@ void run() throws IOException {
72
82
73
83
loadQuestions ();
74
84
75
- this . coordinates = getCoordinates ();
85
+ coordinates = getCoordinates ();
76
86
InteractiveTaskUtils .closeSection ();
77
87
78
88
Path coordinatesMetadataRoot = getProject ().file (CoordinateUtils .replace ("metadata/$group$/$artifact$" , coordinates )).toPath ();
@@ -98,7 +108,7 @@ void run() throws IOException {
98
108
createStubs (isExistingLibrary );
99
109
updateAllowedPackages (packages , isExistingLibrary );
100
110
101
- // generate necessary infrastructure
111
+ // generate necessary boilerplate code
102
112
addTests (testsLocation );
103
113
addResources (resourcesLocation );
104
114
addDockerImages (dockerImages );
@@ -112,11 +122,11 @@ void run() throws IOException {
112
122
// create a PR
113
123
boolean shouldCreatePR = shouldCreatePullRequest ();
114
124
if (shouldCreatePR ) {
115
- String branch = "add-support-for-" + coordinates .toString ().replace (':' , '-' );
125
+ String branch = BRANCH_NAME_PREFIX + coordinates .toString ().replace (':' , '-' );
116
126
createPullRequest (branch );
117
127
118
128
InteractiveTaskUtils .printUserInfo ("After your pull requests gets generated, please update the pull request description to mention all places where your pull request" +
119
- "accesses files, network, docker, or any other external service, and check if all checks in the description are correctly marked" );
129
+ "accesses files, network, docker, or any other external service, and check if all checks in the description are correctly marked. " );
120
130
}
121
131
122
132
InteractiveTaskUtils .printSuccessfulStatement ("Contribution successfully completed! Thank you!" );
@@ -125,15 +135,11 @@ void run() throws IOException {
125
135
private Coordinates getCoordinates () {
126
136
ContributingQuestion question = questions .get ("coordinates" );
127
137
return InteractiveTaskUtils .askQuestion (question .question (), question .help (), (answer ) -> {
128
- String [] coordinatesParts = answer .split (":" );
129
- if (coordinatesParts .length != 3 ) {
130
- throw new IllegalStateException ("Maven coordinates not provided in the correct format. Type help for explanation." );
138
+ try {
139
+ return CoordinateUtils .fromString (answer );
140
+ } catch (IllegalArgumentException ex ) {
141
+ throw new ContributingException (ex .getMessage ());
131
142
}
132
-
133
- String group = coordinatesParts [0 ];
134
- String artifact = coordinatesParts [1 ];
135
- String version = coordinatesParts [2 ];
136
- return new Coordinates (group , artifact , version );
137
143
});
138
144
}
139
145
@@ -142,11 +148,11 @@ private Path getTestsLocation() {
142
148
return InteractiveTaskUtils .askQuestion (question .question (), question .help (), (answer ) -> {
143
149
Path testsLocation = Path .of (answer ).toAbsolutePath ();
144
150
if (!Files .exists (testsLocation )) {
145
- throw new IllegalStateException ("Cannot find tests directory on the given location: " + testsLocation + ". Type help for explanation." );
151
+ throw new ContributingException ("Cannot find tests directory on the given location: " + testsLocation + ". Type help for explanation." );
146
152
}
147
153
148
154
if (!Files .isDirectory (testsLocation )) {
149
- throw new IllegalStateException ("Provided path does not represent a directory: " + testsLocation + ". Type help for explanation." );
155
+ throw new ContributingException ("Provided path does not represent a directory: " + testsLocation + ". Type help for explanation." );
150
156
}
151
157
152
158
checkPackages (testsLocation );
@@ -155,32 +161,32 @@ private Path getTestsLocation() {
155
161
});
156
162
}
157
163
158
- private void checkPackages (Path testsPath ) {
164
+ private void checkPackages (Path testsPath ) throws ContributingException {
159
165
List <Path > javaFiles = new ArrayList <>();
160
166
try {
161
167
FilesUtils .findJavaFiles (testsPath , javaFiles );
162
168
} catch (IOException e ) {
163
- throw new RuntimeException ("Cannot find java files. Reason: " + e );
169
+ throw new ContributingException ("Cannot find java files. Reason: " + e );
164
170
}
165
171
166
- javaFiles . forEach ( file -> {
172
+ for ( Path file : javaFiles ) {
167
173
try {
168
174
Optional <String > packageLine = Files .readAllLines (file ).stream ().filter (line -> line .contains ("package " )).findFirst ();
169
175
if (packageLine .isEmpty ()) {
170
- throw new RuntimeException ("Java file: " + file + " does not contain declared package" );
176
+ throw new ContributingException ("Java file: " + file + " does not contain declared package" );
171
177
}
172
178
173
179
String declaredPackage = packageLine .get ().split (" " )[1 ].replace (";" , "" );
174
180
String packagePath = declaredPackage .replace ("." , File .separator );
175
181
if (!Files .exists (testsPath .resolve (packagePath ))) {
176
- throw new IllegalStateException ("File: " + file + " has package: " + declaredPackage +
182
+ throw new ContributingException ("File: " + file + " has package: " + declaredPackage +
177
183
" that cannot be found on tests location: " + testsPath +
178
184
". Please make sure that the location you provided is a directory that contains packages with tests implementations" );
179
185
}
180
186
} catch (IOException e ) {
181
- throw new RuntimeException ( e );
187
+ throw new ContributingException ( e . getMessage () );
182
188
}
183
- });
189
+ }
184
190
}
185
191
186
192
private Path getResourcesLocation (){
@@ -192,11 +198,11 @@ private Path getResourcesLocation(){
192
198
193
199
Path resourcesLocation = Path .of (answer ).toAbsolutePath ();
194
200
if (!Files .exists (resourcesLocation )) {
195
- throw new IllegalStateException ("Cannot find resources directory on the given location: " + resourcesLocation + ". Type help for explanation." );
201
+ throw new ContributingException ("Cannot find resources directory on the given location: " + resourcesLocation + ". Type help for explanation." );
196
202
}
197
203
198
204
if (!Files .isDirectory (resourcesLocation )) {
199
- throw new IllegalStateException ("Provided path does not represent a directory: " + resourcesLocation + ". Type help for explanation." );
205
+ throw new ContributingException ("Provided path does not represent a directory: " + resourcesLocation + ". Type help for explanation." );
200
206
}
201
207
202
208
return resourcesLocation ;
@@ -210,7 +216,7 @@ private List<String> getDockerImages() {
210
216
while (true ) {
211
217
String nextImage = InteractiveTaskUtils .askQuestion (question .question (), question .help (), answer -> {
212
218
if (!answer .equalsIgnoreCase ("-" ) && answer .split (":" ).length != 2 ) {
213
- throw new IllegalStateException ("Docker image name not provided in the correct format. Type help for explanation." );
219
+ throw new ContributingException ("Docker image name not provided in the correct format. Type help for explanation." );
214
220
}
215
221
216
222
return answer ;
@@ -255,15 +261,11 @@ private List<Coordinates> getAdditionalDependencies() {
255
261
return null ;
256
262
}
257
263
258
- String [] coordinatesParts = answer .split (":" );
259
- if (coordinatesParts .length != 3 ) {
260
- throw new IllegalStateException ("Maven coordinates not provided in the correct format. Type help for explanation." );
264
+ try {
265
+ return CoordinateUtils .fromString (answer );
266
+ } catch (IllegalArgumentException ex ) {
267
+ throw new ContributingException (ex .getMessage ());
261
268
}
262
-
263
- String group = coordinatesParts [0 ];
264
- String artifact = coordinatesParts [1 ];
265
- String version = coordinatesParts [2 ];
266
- return new Coordinates (group , artifact , version );
267
269
});
268
270
269
271
if (dependency == null ) {
@@ -378,7 +380,7 @@ private void addUserCodeFilterFile(List<String> packages) throws IOException {
378
380
objectMapper .writer (prettyPrinter ).writeValue (testsDirectory .resolve (USER_CODE_FILTER_FILE ).toFile (), Map .of ("rules" , filterFileRules ));
379
381
}
380
382
381
- private void addAdditionalDependencies (List <Coordinates > dependencies ) {
383
+ private void addAdditionalDependencies (List <Coordinates > dependencies ) throws IOException {
382
384
if (dependencies == null ) {
383
385
return ;
384
386
}
@@ -390,27 +392,23 @@ private void addAdditionalDependencies(List<Coordinates> dependencies) {
390
392
throw new RuntimeException ("Cannot add additional dependencies to " + buildFilePath + ". Please check if a " + BUILD_FILE + " exists on that location." );
391
393
}
392
394
393
- try {
394
- ConfigurationStringBuilder sb = new ConfigurationStringBuilder ();
395
- List <String > content = Files .readAllLines (buildFilePath );
396
- for (var line : content ) {
397
- sb .append (line ).newLine ();
398
- if (line .trim ().equalsIgnoreCase ("dependencies {" )) {
399
- sb .indent ();
400
- for (var dependency : dependencies ) {
401
- sb .append ("testImplementation" ).space ().quote (dependency .toString ()).newLine ();
402
- }
403
- sb .unindent ();
395
+ ConfigurationStringBuilder sb = new ConfigurationStringBuilder ();
396
+ List <String > content = Files .readAllLines (buildFilePath );
397
+ for (var line : content ) {
398
+ sb .append (line ).newLine ();
399
+ if (line .trim ().equalsIgnoreCase ("dependencies {" )) {
400
+ sb .indent ();
401
+ for (var dependency : dependencies ) {
402
+ sb .append ("testImplementation" ).space ().quote (dependency .toString ()).newLine ();
404
403
}
404
+ sb .unindent ();
405
405
}
406
-
407
- writeToFile (buildFilePath , sb .toString (), StandardOpenOption .WRITE );
408
- } catch (IOException e ) {
409
- throw new RuntimeException (e );
410
406
}
407
+
408
+ writeToFile (buildFilePath , sb .toString (), StandardOpenOption .WRITE );
411
409
}
412
410
413
- private void addAgentConfigBlock () {
411
+ private void addAgentConfigBlock () throws IOException {
414
412
Path buildFilePath = testsDirectory .resolve (BUILD_FILE );
415
413
InteractiveTaskUtils .printUserInfo ("Configuring agent block in: " + BUILD_FILE );
416
414
@@ -425,8 +423,6 @@ private void addAgentConfigBlock() {
425
423
426
424
String content = System .lineSeparator () + (new String (stream .readAllBytes (), StandardCharsets .UTF_8 ));
427
425
writeToFile (buildFilePath , content , StandardOpenOption .APPEND );
428
- } catch (IOException e ) {
429
- throw new RuntimeException ("Cannot add agent block into: " + buildFilePath );
430
426
}
431
427
}
432
428
0 commit comments