@@ -22,13 +22,14 @@ data Project
2222 list [str ] srcs = [], // override source calculation
2323 set [str ] ignores = {}, // directories to ignore
2424 bool parallel = false ,
25- set [str ] parallelPreCheck = {}
25+ set [str ] parallelPreCheck = {},
26+ set [str ] testPrefixes ={}
2627 );
2728
2829alias Projects = rel [str name , Project config ];
2930
3031Projects projects = {
31- <"rascal" , project (|https://github.com/usethesource/rascal.git| , {}, srcs = ["src/org/rascalmpl/library" ], ignores ={"experiments" , "resource" , "lang/rascal/tests" , "lang/rascal/syntax/test " }, parallel = true , parallelPreCheck = {"src/org/rascalmpl/library/Prelude.rsc" })>,
32+ <"rascal" , project (|https://github.com/usethesource/rascal.git| , {}, srcs = ["src/org/rascalmpl/library" ], ignores ={"experiments" , "resource" , "lang/rascal/tests" , "lang/rascal/syntax/tests" , "lang/rascal/grammar/tests " }, parallel = true , parallelPreCheck = {"src/org/rascalmpl/library/Prelude.rsc" })>,
3233 <"rascal-all" , project (|https://github.com/usethesource/rascal.git| , {}, branch =(getSystemProperties ()["RASCAL_ALL_BRANCH" ] ? "main" ), ignores ={"lang/rascal/tutor/examples" , "NestedOr.rsc" }, parallel = true , parallelPreCheck = {"src/org/rascalmpl/library/Prelude.rsc" , "src/org/rascalmpl/compiler/lang/rascalcore/check/CheckerCommon.rsc" })>,
3334 <"typepal" , project (|https://github.com/usethesource/typepal.git| , {"rascal" }, ignores ={"examples" })>,
3435 <"typepal-boot" , project (|https://github.com/usethesource/typepal.git| , {}, rascalLib =true , ignores ={"examples" })>,
@@ -43,7 +44,7 @@ Projects projects = {
4344 <"rascal-git" , project (|https://github.com/cwi-swat/rascal-git.git| , {"rascal" })>,
4445 <"php-analysis" , project (|https://github.com/cwi-swat/php-analysis.git| , {"rascal" , "rascal-git" }, srcs =["src/main/rascal" ])>,
4546 <"rascal-lsp-all" , project (|https://github.com/usethesource/rascal-language-servers.git| , {"rascal-all" }, subdir ="rascal-lsp" , srcs =["src/main/rascal/library" ,"src/main/rascal/lsp" ])>,
46- <"rascal-lsp" , project (|https://github.com/usethesource/rascal-language-servers.git| , {"rascal" , "typepal" }, srcs =["src/main/rascal/library" ], subdir ="rascal-lsp" )>
47+ <"rascal-lsp" , project (|https://github.com/usethesource/rascal-language-servers.git| , {"rascal" , "typepal" }, srcs =["src/main/rascal/library" , "src/main/rascal/lsp" ], ignores = { "lang/rascal/lsp/refactor" , "lang/rascal/tests/rename" , "lang/rascal/lsp/IDECheckerWrapper.rsc" }, subdir ="rascal-lsp" , testPrefixes ={ "lang::rascal::tests::rename" } )>
4748};
4849
4950bool isWindows = /win/i := getSystemProperty ("os.name" );
@@ -159,7 +160,10 @@ list[str] addParallelFlags(Project proj, list[loc] rascalFiles, int maxCores) {
159160 return result ;
160161}
161162
162- lrel [str , int , int ] stats = [];
163+ // Resolve this location before our working directory is irreparably changed later on
164+ loc testWrapperLocation = resolveLocation (|cwd:///src/main/rascal/TestWrapper.rsc| );
165+
166+ lrel [str project , str task , int code , int time ] stats = [];
163167
164168int main (
165169 str memory = "4G" ,
@@ -175,6 +179,8 @@ int main(
175179 set [str ] tests = {/*all*/ }
176180 ) {
177181
182+ repoFolder = resolveLocation (repoFolder ); // get rid of any relative schemes
183+
178184 loc getProjectLoc (str projectName ) {
179185 int res = updateRepos ({p | p :<projectName , _> <- projects }, repoFolder , full );
180186 if (res != 0 ) {
@@ -235,21 +241,79 @@ int main(
235241 iprintln (p );
236242 loc projectRoot = repoFolder + n ;
237243 rProjectRoot = resolveLocation (projectRoot );
238- rascalFiles = [*find (s , "rsc" ) | s <- p .srcs , (startsWith (s .path , projectRoot .path ) || startsWith (s .path , rProjectRoot .path ))];
239- rascalFiles = sort ([f | f <- rascalFiles , !isIgnored (f , p .ignores )]);
244+ rascalFiles = sort ([*find (s , "rsc" ) | s <- p .srcs , (startsWith (s .path , projectRoot .path ) || startsWith (s .path , rProjectRoot .path ))]);
245+ sourceFiles = [f | f <- rascalFiles , !isIgnored (f , p .ignores )];
246+ testModules = sort ([mname | f <- rascalFiles , str mname := getModuleName (f , p ), any (pref <- proj .testPrefixes , startsWith (mname , pref ))]);
240247
241- result += run ("org.rascalmpl.shell.RascalCompile" , n , rProjectRoot , p , rascalFiles , memory , rascalVersion , collectStats = true , extraArgs = [*addParallelFlags (proj , rascalFiles , maxCores ), "-modules" , *[ "<f > " | f <- rascalFiles ]]);
248+ result += run ("org.rascalmpl.shell.RascalCompile" , n , rProjectRoot , p , sourceFiles , memory , rascalVersion , extraArgs = [*addParallelFlags (proj , sourceFiles , maxCores ), "-modules" , *[ "<f > " | f <- sourceFiles ]]);
242249 if (package ) {
243- result += run ("org.rascalmpl.shell.RascalPackage" , n , rProjectRoot , p , rascalFiles , memory , rascalVersion , extraArgs = ["-sourceLookup" , "<rascalVersion > " , "-relocatedClasses" , "<resolve (rProjectRoot , packageTarget )> " ]);
250+ result += run ("org.rascalmpl.shell.RascalPackage" , n , rProjectRoot , p , sourceFiles , memory , rascalVersion , extraArgs = ["-sourceLookup" , "<rascalVersion > " , "-relocatedClasses" , "<resolve (rProjectRoot , packageTarget )> " ]);
244251 }
252+ result += runTests (testModules , rascalVersion , repoFolder , n , proj , p , pcfgs );
245253 }
246254 println ("******\n Done running " );
247- for (<n , e , t > <- stats ) {
248- println ("- <n > <e == 0 ? "✅" : "❌" > <t > s" );
255+ for (p <- toSet (stats .project )) {
256+ println ("- <p > " );
257+ timeWidth = size ("<max (stats [p ]<2 > )>" );
258+ for (<n , e , t > <- stats [p ]) {
259+ println (" <e == 0 ? "✅" : "❌" > <right ("<t > " , timeWidth )> s: <n > " );
260+ }
249261 }
250262 return result ;
251263}
252264
265+ str findUniqueName (str basename , loc dir , str extension = "rsc" ) {
266+ if (!exists (dir + "<basename > .<extension > " )) {
267+ return basename ;
268+ }
269+
270+ int n = 1 ;
271+ int MAX_N = 100 ;
272+ while (exists (dir + "<basename ><n > .<extension > " ) && n < MAX_N ) {
273+ n += 1 ;
274+ }
275+ if (n == MAX_N ) {
276+ throw "Cannot find unique file name for <basename > .<extension > in <dir > " ;
277+ }
278+ return "<basename ><n > " ;
279+ }
280+
281+ loc copyAndRename (loc fromLoc , loc toFolder , str newName , str oldName = "TestWrapper" ) {
282+ dest = toFolder + "<newName > .rsc" ;
283+ writeFile (dest , replaceAll (readFile (fromLoc ), oldName , newName ));
284+ return dest ;
285+ }
286+
287+ int runTests (list [str ] testModules , loc rascalVersion , loc repoFolder , str projectName , Project proj , PathConfig pcfg , lrel [str , PathConfig ] pcfgs ) {
288+ int code = 0 ;
289+ if ({} !:= proj .testPrefixes ) {
290+ println ("*** Starting: test runner on <projectName > (<size (testModules )> )" );
291+
292+ // Prepare test wrapper
293+ destDir = getFirstFrom (pcfg .srcs );
294+ testWrapperName = findUniqueName ("TestWrapper" , destDir );
295+ testWrapperDest = copyAndRename (testWrapperLocation , destDir , testWrapperName );
296+
297+ // Prepare environment
298+ envVars = ("ADDITIONAL_TPLS" : "<resolveLocation (rpcfg .bin )> " | rpcfg <- pcfgs ["rascal" ]);
299+
300+ startTime = realTime ();
301+ try {
302+ pid = createProcess ("java" , args = ["-jar" , buildFSPath (rascalVersion ), testWrapperName , "--testModules" , intercalate ("," , testModules )], workingDir = projectRoot (repoFolder , projectName , proj ), envVars = envVars );
303+ code = awaitProcess (pid );
304+ } catch e : {
305+ throw e ;
306+ } finally {
307+ stopTime = realTime ();
308+ remove (testWrapperDest );
309+ elapsedTime = (stopTime - startTime ) / 1000;
310+ println("*** Finished: test runner on <projectName > < code == 0 ? "✅" : "❌ Failed with error <code > " > (<elapsedTime > s)");
311+ stats += <projectName , "tests" , code , elapsedTime > ;
312+ }
313+ }
314+ return code;
315+ }
316+
253317int run(
254318 str class,
255319 str projectName,
@@ -258,7 +322,6 @@ int run(
258322 list[loc] rascalFiles,
259323 str memory,
260324 loc rascalVersion,
261- bool collectStats = false ,
262325 list[str] extraArgs = []
263326) {
264327 result = 0;
@@ -275,34 +338,51 @@ int run(
275338 "-bin" , "<pcfg .bin > " ,
276339 *extraArgs
277340 ]);
341+ try {
342+ code = awaitProcess (runner );
343+ result += code ;
344+ stopTime = realTime ();
345+ elapsedTime = (stopTime - startTime ) / 1000;
346+ println("*** Finished: <class > on <projectName > < code == 0 ? "✅" : "❌ Failed with error <code > " > (<elapsedTime > s)");
347+ stats += <projectName , class , code , elapsedTime > ;
348+ }
349+ catch ex :{
350+ println("Running the runner for <projectName > crashed with <ex > ");
351+ result += 1;
352+ }
353+ return result;
354+ }
355+
356+ int awaitProcess(int runner, bool printStdOut = true, bool printStdErr = true) {
357+ int code = -1;
278358 try {
279359 while (isAlive(runner)) {
280360 stdOut = readWithWait(runner, 500);
281- if (stdOut != "" ) {
361+ if (printStdOut && stdOut != "") {
282362 print(stdOut);
283363 }
284- stdErr = readFromErr (runner );
285- while (stdErr != "" ) {
286- println (stdErr );
364+ if (printStdErr) {
287365 stdErr = readFromErr(runner);
366+ while (stdErr != "") {
367+ println(stdErr);
368+ stdErr = readFromErr(runner);
369+ }
288370 }
289371 }
290- stopTime = realTime ();
291- println (readEntireStream (runner ));
292- println (readEntireErrStream (runner ));
293- code = exitCode (runner );
294- result += code ;
295- println ("*** Finished: <class > on <projectName > < code == 0 ? "✅" : "❌ Failed with error <code > " > (<(stopTime - startTime )/1000>s)");
296- if (collectStats) {
297- stats += <projectName , code , (stopTime - startTime )/1000>;
372+ if (printStdOut) {
373+ println(readEntireStream(runner));
374+ }
375+ if (printStdErr) {
376+ println(readEntireErrStream(runner));
298377 }
378+ code = exitCode(runner);
299379 }
300380 catch ex :{
301- println("Running the runner for <projectName > crashed with <ex > ");
302- result += 1;
381+ throw ex;
303382 }
304383 finally {
305384 killProcess(runner);
385+ return code;
306386 }
307- return result ;
387+ return code ;
308388}
0 commit comments