@@ -441,7 +441,35 @@ private enum FileTrackMode {
441441 private File modifiedSrcBuildFile ;
442442
443443 protected boolean skipInstallFeature ;
444+ // for gradle, this map will be kept as null
445+ protected Map <String , Boolean > projectRecompileMap ;
444446
447+ // constructor for maven
448+ public DevUtil (File buildDirectory , File serverDirectory , File sourceDirectory , File testSourceDirectory ,
449+ File configDirectory , File projectDirectory , File multiModuleProjectDirectory , List <File > resourceDirs , boolean changeOnDemandTestsAction ,
450+ boolean hotTests , boolean skipTests , boolean skipUTs , boolean skipITs , boolean skipInstallFeature , String applicationId ,
451+ long serverStartTimeout , int appStartupTimeout , int appUpdateTimeout , long compileWaitMillis ,
452+ boolean libertyDebug , boolean useBuildRecompile , boolean gradle , boolean pollingTest , boolean container ,
453+ File containerfile , File containerBuildContext , String containerRunOpts , int containerBuildTimeout ,
454+ boolean skipDefaultPorts , JavaCompilerOptions compilerOptions , boolean keepTempContainerfile ,
455+ String mavenCacheLocation , List <ProjectModule > upstreamProjects , boolean recompileDependencies ,
456+ String packagingType , File buildFile , Map <String , List <String >> parentBuildFiles , boolean generateFeatures ,
457+ Set <String > compileArtifactPaths , Set <String > testArtifactPaths , List <Path > monitoredWebResourceDirs , Map <String , Boolean > projectRecompileMap ) {
458+ this (buildDirectory , serverDirectory , sourceDirectory , testSourceDirectory ,
459+ configDirectory , projectDirectory , multiModuleProjectDirectory , resourceDirs , changeOnDemandTestsAction ,
460+ hotTests , skipTests , skipUTs , skipITs , skipInstallFeature , applicationId ,
461+ serverStartTimeout , appStartupTimeout , appUpdateTimeout , compileWaitMillis ,
462+ libertyDebug , useBuildRecompile , gradle , pollingTest , container ,
463+ containerfile , containerBuildContext , containerRunOpts , containerBuildTimeout ,
464+ skipDefaultPorts , compilerOptions , keepTempContainerfile ,
465+ mavenCacheLocation , upstreamProjects , recompileDependencies ,
466+ packagingType , buildFile , parentBuildFiles , generateFeatures ,
467+ compileArtifactPaths , testArtifactPaths , monitoredWebResourceDirs );
468+ // setting projectRecompileMap as empty if input is null from ci.maven
469+ this .projectRecompileMap = projectRecompileMap != null ? projectRecompileMap : new HashMap <>();
470+ }
471+
472+ // constructor for gradle
445473 public DevUtil (File buildDirectory , File serverDirectory , File sourceDirectory , File testSourceDirectory ,
446474 File configDirectory , File projectDirectory , File multiModuleProjectDirectory , List <File > resourceDirs , boolean changeOnDemandTestsAction ,
447475 boolean hotTests , boolean skipTests , boolean skipUTs , boolean skipITs , boolean skipInstallFeature , String applicationId ,
@@ -491,6 +519,7 @@ public DevUtil(File buildDirectory, File serverDirectory, File sourceDirectory,
491519 this .containerfile = containerfile ;
492520 this .containerBuildContext = containerBuildContext ;
493521 this .containerRunOpts = containerRunOpts ;
522+
494523 if (projectDirectory != null ) {
495524 //Use Containerfile if it exists, but default to Dockerfile if both present or neither exist
496525 File defaultDockerFile = new File (projectDirectory , "Dockerfile" );
@@ -3597,9 +3626,11 @@ private boolean processUpstreamJavaCompilation(List<ProjectModule> upstreamProje
35973626 boolean successfulCompilation = true ;
35983627 boolean compileDownstreamSrc = false ;
35993628 boolean compileDownstreamTest = false ;
3600-
3601- boolean pastBuildFileWaitPeriod = System
3602- .currentTimeMillis () > lastBuildFileChange .get (project .getBuildFile ()) + compileWaitMillis ;
3629+ boolean pastBuildFileWaitPeriod = true ;
3630+ if (lastBuildFileChange .get (project .getBuildFile ()) != null ) {
3631+ pastBuildFileWaitPeriod = System
3632+ .currentTimeMillis () > lastBuildFileChange .get (project .getBuildFile ()) + compileWaitMillis ;
3633+ }
36033634 if (!pastBuildFileWaitPeriod ) {
36043635 continue ;
36053636 }
@@ -3856,7 +3887,12 @@ private void processJavaCompilation(File outputDirectory, File testOutputDirecto
38563887 // process java source files if no changes detected after the compile wait time
38573888 boolean processSources = System .currentTimeMillis () > lastJavaSourceChange + compileWaitMillis ;
38583889 boolean processTests = System .currentTimeMillis () > lastJavaTestChange + compileWaitMillis ;
3859- boolean pastBuildFileWaitPeriod = System .currentTimeMillis () > lastBuildFileChange .get (buildFile ) + compileWaitMillis ;
3890+ boolean pastBuildFileWaitPeriod = true ;
3891+ if (lastBuildFileChange .get (buildFile ) != null ) {
3892+ pastBuildFileWaitPeriod = System
3893+ .currentTimeMillis () > lastBuildFileChange .get (buildFile ) + compileWaitMillis ;
3894+ }
3895+
38603896 if (processSources && pastBuildFileWaitPeriod ) {
38613897 // Count the messages before the compile.
38623898 int numApplicationUpdatedMessages = 0 ;
@@ -4021,16 +4057,40 @@ private void initWatchLoop() throws IOException {
40214057 // initial source and test compile of upstream projects
40224058 if (isMultiModuleProject ()) {
40234059 for (ProjectModule project : upstreamProjects ) {
4024- triggerUpstreamModuleCompile (project , false );
4025- // build file tracking of upstream projects
4026- lastBuildFileChange .put (project .getBuildFile (), System .currentTimeMillis ());
4060+ // for ci.gradle, map will be null always
4061+ // we can always trigger recompile for gradle, as we gradle is using gradle task state to recompile
4062+ if (projectRecompileMap == null ) {
4063+ info ("Recompile " + project .getProjectName ());
4064+ triggerUpstreamModuleCompile (project , false );
4065+ // build file tracking of upstream projects, this update is needed for auto test invocation
4066+ lastBuildFileChange .put (project .getBuildFile (), System .currentTimeMillis ());
4067+ } else if (Boolean .TRUE .equals (projectRecompileMap .get (project .getProjectName ()))) {
4068+ info ("Recompile " + project .getProjectName () + " due to an earlier compilation error" );
4069+ triggerUpstreamModuleCompile (project , false );
4070+ // build file tracking of upstream projects, this update is needed for auto test invocation
4071+ lastBuildFileChange .put (project .getBuildFile (), System .currentTimeMillis ());
4072+ } else {
4073+ info ("Recompile skipped for " + project .getProjectName () + " since earlier compilation is successful" );
4074+ }
40274075 }
40284076 }
40294077
4030- // initial source and test compile
4031- triggerMainModuleCompile (false );
4032- // build file tracking of main project
4033- lastBuildFileChange .put (buildFile , System .currentTimeMillis ());
4078+ // for ci.gradle, map will be null always
4079+ // we can always trigger recompile for gradle, as we gradle is using gradle task state to recompile
4080+ if (projectRecompileMap == null ) {
4081+ info ("Recompile " + getProjectName ());
4082+ triggerMainModuleCompile (false );
4083+ // build file tracking of upstream projects, this update is needed for auto test invocation
4084+ lastBuildFileChange .put (buildFile , System .currentTimeMillis ());
4085+ } else if (Boolean .TRUE .equals (projectRecompileMap .get (getProjectName ()))) {
4086+ info ("Recompile " + getProjectName () + " due to an earlier compilation error" );
4087+ triggerMainModuleCompile (false );
4088+ // build file tracking of upstream projects, this update is needed for auto test invocation
4089+ lastBuildFileChange .put (buildFile , System .currentTimeMillis ());
4090+ } else {
4091+ info ("Recompile skipped for " + getProjectName () + " since earlier compilation is successful" );
4092+ }
4093+
40344094 }
40354095
40364096 private void processFileChanges (
0 commit comments