Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Gradle multi module 2.0 #918

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 37 additions & 40 deletions src/main/groovy/io/openliberty/tools/gradle/tasks/DevTask.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ import io.openliberty.tools.common.plugins.util.ServerFeatureUtil
import io.openliberty.tools.common.plugins.util.ServerFeatureUtil.FeaturesPlatforms
import io.openliberty.tools.common.plugins.util.ServerStatusUtil
import io.openliberty.tools.gradle.utils.DevTaskHelper
import io.openliberty.tools.gradle.utils.LooseWarApplication
import org.gradle.api.GradleException
import org.gradle.api.Project
import org.gradle.api.artifacts.Configuration
Expand Down Expand Up @@ -378,14 +377,14 @@ class DevTask extends AbstractFeatureTask {
boolean libertyDebug, boolean pollingTest, boolean container, File containerfile, File containerBuildContext,
String containerRunOpts, int containerBuildTimeout, boolean skipDefaultPorts, boolean keepTempContainerfile,
String mavenCacheLocation, String packagingType, File buildFile, boolean generateFeatures, List<Path> webResourceDirs,
List<ProjectModule> projectModuleList
List<ProjectModule> projectModuleList, Map<String, List<String>> parentBuildGradle
) throws IOException, PluginExecutionException {
super(buildDir, serverDirectory, sourceDirectory, testSourceDirectory, configDirectory, projectDirectory, /* multi module project directory */ projectDirectory,
resourceDirs, changeOnDemandTestsAction, hotTests, skipTests, false /* skipUTs */, false /* skipITs */, skipInstallFeature, artifactId, serverStartTimeout,
verifyAppStartTimeout, appUpdateTimeout, ((long) (compileWait * 1000L)), libertyDebug,
true /* useBuildRecompile */, true /* gradle */, pollingTest, container, containerfile, containerBuildContext, containerRunOpts, containerBuildTimeout, skipDefaultPorts,
null /* compileOptions not needed since useBuildRecompile is true */, keepTempContainerfile, mavenCacheLocation, projectModuleList /* multi module upstream projects */,
false /* recompileDependencies only supported in ci.maven */, packagingType, buildFile, null /* parent build files */, generateFeatures, null /* compileArtifactPaths */, null /* testArtifactPaths */, webResourceDirs /* webResources */
projectModuleList.size() > 0 /* recompileDependencies as true for multi module */, packagingType, buildFile, parentBuildGradle /* parent build files */, generateFeatures, null /* compileArtifactPaths */, null /* testArtifactPaths */, webResourceDirs /* webResources */
);
this.libertyDirPropertyFiles = AbstractServerTask.getLibertyDirectoryPropertyFiles(installDirectory, userDirectory, serverDirectory);
ServerFeatureUtil servUtil = getServerFeatureUtil(true, libertyDirPropertyFiles);
Expand Down Expand Up @@ -500,13 +499,21 @@ class DevTask extends AbstractFeatureTask {
@Override
public boolean updateArtifactPaths(ProjectModule projectModule, boolean redeployCheck, boolean generateFeatures, ThreadPoolExecutor executor)
throws PluginExecutionException {
// not supported for Gradle, only used for multi module Maven projects
// for multi module, unable to identify the changes made, showing option for user. return true to trigger recompile
if (isMultiModuleProject()) {
cherylking marked this conversation as resolved.
Show resolved Hide resolved
warn("A change was detected in a build file. The libertyDev task could not determine if a server restart is required. To restart server, type 'r' and press Enter.");
return true;
}
return false;
cherylking marked this conversation as resolved.
Show resolved Hide resolved
}

@Override
public boolean updateArtifactPaths(File parentBuildFile) {
// not supported for Gradle, only used for multi module Maven projects
// for multi module, unable to identify the changes made, showing option for user. return true to trigger recompile
if (isMultiModuleProject()) {
warn("A change was detected in a build file. The libertyDev task could not determine if a server restart is required. To restart server, type 'r' and press Enter.");
return true;
}
return false;
}

Expand Down Expand Up @@ -535,6 +542,11 @@ class DevTask extends AbstractFeatureTask {
boolean restartServer = false;
boolean installFeatures = false;
boolean optimizeGenerateFeatures = false;
// for multi module, unable to identify the changes made, showing option for user. return true to trigger recompile
if (isMultiModuleProject()) {
warn("A change was detected in a build file. The libertyDev task could not determine if a server restart is required. To restart server, type 'r' and press Enter.");
return true;
}

ProjectBuilder builder = ProjectBuilder.builder();
Project newProject;
Expand Down Expand Up @@ -1266,14 +1278,19 @@ class DevTask extends AbstractFeatureTask {
// Project modules contain all child modules. This project modules will be present only for multi-module
// used to watch sub project src and test source files
List<ProjectModule> projectModules = getProjectModules()
// get parent build.gradle to register
Map<String, List<String>> parentBuildGradle = new HashMap<String, List<String>>();
if(projectModules.size()>0) {
DevTaskHelper.updateParentBuildFiles(parentBuildGradle, project)
}
try {
this.util = new DevTaskUtil(project.getLayout().getBuildDirectory().getAsFile().get(), serverInstallDir, getUserDir(project, serverInstallDir),
serverDirectory, sourceDirectory, testSourceDirectory, configDirectory, project.getRootDir(),
resourceDirs, changeOnDemandTestsAction.booleanValue(), hotTests.booleanValue(), skipTests.booleanValue(), skipInstallFeature.booleanValue(), artifactId, serverStartTimeout.intValue(),
verifyAppStartTimeout.intValue(), verifyAppStartTimeout.intValue(), compileWait.doubleValue(),
libertyDebug.booleanValue(), pollingTest.booleanValue(), container.booleanValue(), containerfile, containerBuildContext, containerRunOpts,
containerBuildTimeout, skipDefaultPorts.booleanValue(), keepTempContainerfile.booleanValue(), localMavenRepoForFeatureUtility,
DevTaskHelper.getPackagingType(project), buildFile, generateFeatures.booleanValue(), webResourceDirs, projectModules
DevTaskHelper.getPackagingType(project), buildFile, generateFeatures.booleanValue(), webResourceDirs, projectModules, parentBuildGradle
);
} catch (IOException | PluginExecutionException e) {
throw new GradleException("Error initializing dev mode.", e)
Expand Down Expand Up @@ -1416,8 +1433,10 @@ class DevTask extends AbstractFeatureTask {
private List<ProjectModule> getProjectModules() {
List<ProjectModule> upstreamProjects = new ArrayList<ProjectModule>();
for (Project dependencyProject : DevTaskHelper.getAllUpstreamProjects(project)) {
// TODO get compiler options for upstream project
// JavaCompilerOptions upstreamCompilerOptions = getMavenCompilerOptions(p);
// In Maven , there is a step to set compiler options for upstream project
// Gradle does not need to manually inject compiler options because
// we are directly calling compileJava task, which internally takes the compiler options
// from task definition or command line arguments
JavaCompilerOptions upstreamCompilerOptions = new JavaCompilerOptions();
SourceSet mainSourceSet = dependencyProject.sourceSets.main;
SourceSet testSourceSet = dependencyProject.sourceSets.test;
Expand All @@ -1431,40 +1450,18 @@ class DevTask extends AbstractFeatureTask {
File upstreamTestOutputDir = testOutputDirectory.asFile.get();
// resource directories
List<File> upstreamResourceDirs = mainSourceSet.resources.srcDirs.toList();
/* TODO all gradle items
// properties that are set in the pom file
Properties props = dependencyProject.getProperties();

// properties that are set by user via CLI parameters
Properties userProps = session.getUserProperties();

Plugin libertyPlugin = getLibertyPluginForProject(p);
// use "dev" goal, although we don't expect the skip tests flags to be bound to any goal
Xpp3Dom config = ExecuteMojoUtil.getPluginGoalConfig(libertyPlugin, "dev", getLog());

boolean upstreamSkipTests = DevHelper.getBooleanFlag(config, userProps, props, "skipTests");
boolean upstreamSkipITs = DevHelper.getBooleanFlag(config, userProps, props, "skipITs");
boolean upstreamSkipUTs = DevHelper.getBooleanFlag(config, userProps, props, "skipUTs");

// only force skipping unit test for ear modules otherwise honour existing skip
// test params


// build list of dependent modules
List<MavenProject> dependentProjects = graph.getDownstreamProjects(p, true);
List<File> dependentModules = new ArrayList<File>();
for (MavenProject depProj : dependentProjects) {
dependentModules.add(depProj.getFile());
}
*/
boolean upstreamSkipTests = false
boolean upstreamSkipITs = false
boolean upstreamSkipUTs = false
//get gradle project properties. It is observed that project properties contain all gradle properties
// properties are overridden automatically with the highest precedence
// in gradle, we are only using skipTests
boolean upstreamSkipTests = dependencyProject.hasProperty("skipTests") ? DevTaskHelper.parseBooleanIfDefined(dependencyProject.properties.get("skipTests")) : skipTests

if (DevTaskHelper.getPackagingType(dependencyProject).equals("ear")) {
upstreamSkipUTs = true;
}
// build list of dependent modules
// build list of dependent modules -> can be kept as empty list for gradle
// In gradle multi module project, we are calling compileJava for ear
// Then gradle internally identifies other transitive project dependencies and calls compileJava for each of them
// gradle checks whether the task is UP TO DATE, if its already UP TO DATE, it wont be triggered again
List<File> dependentModules = new ArrayList<File>();
ProjectModule upstreamProject = new ProjectModule(dependencyProject.getBuildFile(),
dependencyProject.getName(),
Expand All @@ -1477,8 +1474,8 @@ class DevTask extends AbstractFeatureTask {
upstreamTestOutputDir,
upstreamResourceDirs,
upstreamSkipTests,
upstreamSkipUTs,
upstreamSkipITs,
false,
false,
upstreamCompilerOptions,
dependentModules);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,4 +150,32 @@ public class DevTaskHelper {
retVal.add(war.getWebAppDirectory().get().asFile.toPath().toAbsolutePath())
}
}

/**
* Parses a Boolean from a Object if the Object is not null. Otherwise returns null.
* @param value the Object to parse
* @return a Boolean, or null if value is null
*/
public static Boolean parseBooleanIfDefined(Object value) {
if (value != null) {
return Boolean.parseBoolean(value as String);
}
return null;
}

/**
* Update map with list of parent build files and their subsequent child build files
*
* @param parentBuildFiles Map of parent build files and subsequent child build files
* @param proj GradleProject
*/
public static void updateParentBuildFiles(Map<String, List<String>> parentBuildFiles, Project proj) {
String parentBuildGradle = proj.getRootProject().getBuildFile().getCanonicalPath()
List<String> childBuildFiles = new ArrayList<>();
childBuildFiles.add(proj.getBuildFile().getCanonicalPath())
for (Project dependencyProject : getAllUpstreamProjects(proj)) {
childBuildFiles.add(dependencyProject.getBuildFile().getCanonicalPath())
}
parentBuildFiles.put(parentBuildGradle, childBuildFiles)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class TestMultiModuleLooseEarAppDevMode extends BaseDevTest {
createDir(buildDir);
createTestProject(buildDir, resourceDir, buildFilename);
new File(buildDir, "build").createNewFile();
runDevMode(buildDir)
runDevMode("--skipTests", buildDir)
}

@Test
Expand All @@ -36,7 +36,42 @@ class TestMultiModuleLooseEarAppDevMode extends BaseDevTest {
javaWriter.append(str);
javaWriter.close();

assertTrue(waitForCompilation(targetHelloWorld, lastModified, 6000));
assertTrue(waitForCompilation(targetHelloWorld, lastModified, 123000));
}

@Test
public void manualTestsInvocationTest() throws Exception {
waitLongEnough();
writer.write("\n");
writer.flush();
if (!verifyLogMessage(123000, "Tests will not run on demand for ear because skipTests is set to true")) {
assertTrue(verifyLogMessage(123000, "Tests will not run on demand for ear because skipTests is set to true"));
}
if (!verifyLogMessage(6000, "Tests will not run on demand for jar because skipTests is set to true")) {
assertTrue(verifyLogMessage(6000, "Tests will not run on demand for jar because skipTests is set to true"));
}
if (!verifyLogMessage(6000, "Tests will not run on demand for war because skipTests is set to true")) {
assertTrue(verifyLogMessage(6000, "Tests will not run on demand for war because skipTests is set to true"));
}

}

@Test
public void modifyUpdateGradleTest() throws Exception {
waitLongEnough();
// modify a java file
File srcHelloWorld = new File(buildDir, "build.gradle");
assertTrue(srcHelloWorld.exists());

String str = "// testing";
BufferedWriter javaWriter = new BufferedWriter(new FileWriter(srcHelloWorld, true));
javaWriter.append(' ');
javaWriter.append(str);
javaWriter.close();

if (!verifyLogMessage(123000, "A change was detected in a build file. The libertyDev task could not determine if a server restart is required. To restart server, type 'r' and press Enter.")) {
assertTrue(verifyLogMessage(123000, "A change was detected in a build file. The libertyDev task could not determine if a server restart is required. To restart server, type 'r' and press Enter."));
}
}

@AfterClass
Expand All @@ -47,4 +82,5 @@ class TestMultiModuleLooseEarAppDevMode extends BaseDevTest {
System.out.println(stderr);
cleanUpAfterClass(true);
}

}
Loading