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

Handle change in installDir between dev mode runs #879

Merged
merged 1 commit into from
Feb 15, 2024
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
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,21 @@ abstract class AbstractLibertyTask extends DefaultTask {
protected String springBootVersion
protected Task springBootTask

protected boolean isInstallDirChanged(Project project) {

XmlParser pluginXmlParser = new XmlParser()
Node libertyPluginConfig = pluginXmlParser.parse(new File(project.buildDir, 'liberty-plugin-config.xml'))
if (!libertyPluginConfig.getAt('installDirectory').isEmpty()) {
Node installDirNode = libertyPluginConfig.getAt('installDirectory').get(0)
File previousInstallDir = new File(installDirNode.text())
File currentInstallDir = getInstallDir(project)
if (previousInstallDir.exists() && previousInstallDir.equals(currentInstallDir)) {
return false
}
}
return true
}

protected getInstallDir = { Project project ->
return Liberty.getInstallDir(project);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,8 @@ abstract class AbstractServerTask extends AbstractLibertyTask {
if (serverEnvPath != null && !serverEnvPath.isEmpty()) {
logger.info("Update server configuration file server.env from " + serverEnvPath)
}

writeServerPropertiesToXml(project)
}

private void loadLibertyConfigFromProperties() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* (C) Copyright IBM Corporation 2014, 2023.
* (C) Copyright IBM Corporation 2014, 2024.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -22,6 +22,7 @@ import org.gradle.api.tasks.InputFile
import org.gradle.api.tasks.Optional
import org.gradle.api.tasks.TaskAction
import org.gradle.api.logging.LogLevel
import org.gradle.api.Project

class CreateTask extends AbstractServerTask {

Expand All @@ -33,7 +34,7 @@ class CreateTask extends AbstractServerTask {
group 'Liberty'
})
outputs.upToDateWhen {
getServerDir(project).exists() && (new File(getServerDir(project), 'server.xml')).exists()
getServerDir(project).exists() && (new File(getServerDir(project), 'server.xml')).exists() && !isServerDirChanged(project)
}
}

Expand Down Expand Up @@ -93,7 +94,25 @@ class CreateTask extends AbstractServerTask {
logger.warn("The " + serverXmlFile.getAbsolutePath() + " does not exist. Copying over the defaultServer template server.xml file.")
}
copyConfigFiles()
writeServerPropertiesToXml(project)
}

protected boolean isServerDirChanged(Project project) {
if (!project.buildDir.exists() || !(new File(project.buildDir, 'liberty-plugin-config.xml')).exists()) {
return false
}

XmlParser pluginXmlParser = new XmlParser()
Node libertyPluginConfig = pluginXmlParser.parse(new File(project.buildDir, 'liberty-plugin-config.xml'))
if (!libertyPluginConfig.getAt('serverDirectory').isEmpty()) {
File currentDir = getServerDir(project)
File previousDir = new File(libertyPluginConfig.getAt('serverDirectory')[0].value)
if (previousDir.exists() && previousDir.equals(currentDir)) {
return false
}
return true
}
// if serverDirectory did not exist in the xml file, do not consider this as a change
return false
}

File getLibertyPropertyFile(File libertyPropertyFile, String fileName) {
Expand Down
29 changes: 26 additions & 3 deletions src/main/groovy/io/openliberty/tools/gradle/tasks/DevTask.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -1260,9 +1260,12 @@ class DevTask extends AbstractFeatureTask {
}

if (!isNewInstallation) {
logger.info("Skipping installLiberty task for existing installation.")
// will this cause an issue when changing the runtime? Customer would be forced to cleanup first?
gradleBuildLauncher.addArguments("--exclude-task", "installLiberty"); // skip installing Liberty at startup since it was already installed
// if the install dir changed or this is the first dev mode run on this project, need to give installLiberty task
// a chance to check validity of installation and update info in liberty plugin config xml file.
if (!isInstallDirChanged(project, serverInstallDir)) {
logger.info("Skipping installLiberty task for existing installation.")
gradleBuildLauncher.addArguments("--exclude-task", "installLiberty"); // skip installing Liberty at startup since it is the same installation as previous dev mode run
}
if (skipInstallFeature) {
logger.info("Skipping installFeature task due to skipInstallFeature configuration.")
gradleBuildLauncher.addArguments("--exclude-task", "installFeature"); // skip installing features at startup since flag was set
Expand Down Expand Up @@ -1324,6 +1327,26 @@ class DevTask extends AbstractFeatureTask {
}
}

private boolean isInstallDirChanged(Project project, File currentInstallDir) {
if (project.buildDir.exists() && new File(project.buildDir, 'liberty-plugin-config.xml').exists()) {
XmlParser pluginXmlParser = new XmlParser()
Node libertyPluginConfig = pluginXmlParser.parse(new File(project.buildDir, 'liberty-plugin-config.xml'))
if (!libertyPluginConfig.getAt('installDirectory').isEmpty()) {
Node installDirNode = libertyPluginConfig.getAt('installDirectory').get(0)
String installDirValue = installDirNode.text()
File previousInstallDir = new File(installDirValue)
if (previousInstallDir.exists() && previousInstallDir.equals(currentInstallDir)) {
return false
} else {
logger.info("Detected change in installDir location from "+installDirValue+" to "+currentInstallDir.getAbsolutePath())
return true
}
}
}
return true
}


private void addLibertyRuntimeProperties(BuildLauncher gradleBuildLauncher) {
Set<Entry<Object, Object>> entries = project.getProperties().entrySet()
for (Entry<Object, Object> entry : entries) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* (C) Copyright IBM Corporation 2014, 2023.
* (C) Copyright IBM Corporation 2014, 2024.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -16,6 +16,7 @@
package io.openliberty.tools.gradle.tasks

import javax.xml.parsers.*
import groovy.xml.StreamingMarkupBuilder

import org.gradle.api.Project
import org.gradle.api.tasks.TaskAction
Expand Down Expand Up @@ -52,7 +53,8 @@ class InstallLibertyTask extends AbstractLibertyTask {
outputs.upToDateWhen {
// ensure a Liberty installation exists at the install directory
getInstallDir(project).exists() && new File(getInstallDir(project), 'lib/ws-launch.jar').exists() &&
project.buildDir.exists() && new File(project.buildDir, 'liberty-plugin-config.xml').exists()
project.buildDir.exists() && new File(project.buildDir, 'liberty-plugin-config.xml').exists() &&
!isInstallDirChanged(project)
}
}

Expand Down Expand Up @@ -109,7 +111,9 @@ class InstallLibertyTask extends AbstractLibertyTask {
@TaskAction
void install() {
// If installDir is set, then use the configured wlp or throw error if it is invalid
if(project.liberty.installDir != null && isLibertyInstalledAndValid(project)) {
boolean isExisting = false
if((project.liberty.installDir != null || project.hasProperty('liberty.installDir')) && isLibertyInstalledAndValid(project)) {
isExisting = true
logger.info ("Liberty is already installed at: " + getInstallDir(project))
} else {
def params = buildInstallLibertyMap(project)
Expand All @@ -125,25 +129,94 @@ class InstallLibertyTask extends AbstractLibertyTask {
process.waitFor()
}
}
createPluginXmlFile(isExisting)
}

protected void updatePluginXmlFile() {
XmlParser pluginXmlParser = new XmlParser()
Node libertyPluginConfig = pluginXmlParser.parse(new File(project.buildDir, 'liberty-plugin-config.xml'))

Node installDirNode = libertyPluginConfig.getAt('installDirectory').isEmpty() ? libertyPluginConfig.appendNode('installDirectory') : libertyPluginConfig.getAt('installDirectory').get(0)
installDirNode.setValue(getInstallDir(project).toString())
//logger.info ("Updating liberty-plugin-config.xml installDirectory: " + getInstallDir(project).toString())

if (project.liberty.installDir != null || project.hasProperty('liberty.installDir')) {
// remove stale nodes
if (!libertyPluginConfig.getAt('assemblyArchive').isEmpty()) {
//logger.info ("Updating liberty-plugin-config.xml to remove assemblyArchive")
libertyPluginConfig.remove(libertyPluginConfig.getAt('assemblyArchive').get(0))
}
if (!libertyPluginConfig.getAt('assemblyArtifact').isEmpty()) {
//logger.info ("Updating liberty-plugin-config.xml to remove assemblyArtifact")
libertyPluginConfig.remove(libertyPluginConfig.getAt('assemblyArtifact').get(0))
}
} else if (detachedCoords != null) {
//logger.info ("Updating liberty-plugin-config.xml to update assemblyArtifact and assemblyArchive")
Node assemblyArchive = libertyPluginConfig.getAt('assemblyArchive').isEmpty() ? libertyPluginConfig.appendNode('assemblyArchive') : libertyPluginConfig.getAt('assemblyArchive').get(0)
Node assemblyArtifact = libertyPluginConfig.getAt('assemblyArtifact').isEmpty() ? libertyPluginConfig.appendNode('assemblyArtifact') : libertyPluginConfig.getAt('assemblyArtifact').get(0)

//removes the child nodes from the assemblyArtifact element
assemblyArtifact.value = ""

String[] coords = detachedCoords.split(":")

assemblyArtifact.appendNode('groupId', coords[0])
assemblyArtifact.appendNode('artifactId', coords[1])
assemblyArtifact.appendNode('version', coords[2])
assemblyArtifact.appendNode('type', 'zip')

assemblyArchive.setValue(detachedConfigFilePath)

} else if (project.configurations.libertyRuntime != null) {
//logger.info ("Updating liberty-plugin-config.xml to update assemblyArtifact and assemblyArchive")
Node assemblyArchive = libertyPluginConfig.getAt('assemblyArchive').isEmpty() ? libertyPluginConfig.appendNode('assemblyArchive') : libertyPluginConfig.getAt('assemblyArchive').get(0)
Node assemblyArtifact = libertyPluginConfig.getAt('assemblyArtifact').isEmpty() ? libertyPluginConfig.appendNode('assemblyArtifact') : libertyPluginConfig.getAt('assemblyArtifact').get(0)

//removes the child nodes from the assemblyArtifact element
assemblyArtifact.value = ""

project.configurations.libertyRuntime.dependencies.each { libertyArtifact ->

assemblyArtifact.appendNode('groupId', libertyArtifact.group)
assemblyArtifact.appendNode('artifactId',libertyArtifact.name )
assemblyArtifact.appendNode('version', libertyArtifact.version)
assemblyArtifact.appendNode('type', 'zip')

assemblyArchive.setValue(project.configurations.libertyRuntime.resolvedConfiguration.resolvedArtifacts.getAt(0).file.toString())
}
}

new File( project.buildDir, 'liberty-plugin-config.xml' ).withWriter('UTF-8') { output ->
output << new StreamingMarkupBuilder().bind { mkp.xmlDeclaration(encoding: 'UTF-8', version: '1.0' ) }
XmlNodePrinter printer = new XmlNodePrinter( new PrintWriter(output) )
printer.preserveWhitespace = true
printer.print( libertyPluginConfig )
}

logger.info ("Updating Liberty plugin config info at ${project.buildDir}/liberty-plugin-config.xml.")

createPluginXmlFile()
}

protected void createPluginXmlFile() {
protected void createPluginXmlFile(boolean isExisting) {
if(!this.state.upToDate) {
if (!project.buildDir.exists()) {
logger.info ("Creating missing project buildDir at ${project.buildDir}.")
project.buildDir.mkdirs()
}

new File(project.buildDir, 'liberty-plugin-config.xml').withWriter { writer ->
def xmlDoc = new MarkupBuilder(writer)
xmlDoc.mkp.xmlDeclaration(version: "1.0", encoding: "UTF-8")
xmlDoc.'liberty-plugin-config'('version':'2.0') {
outputLibertyPropertiesToXml(xmlDoc)
// if the file already exists, update it instead of replacing it
if (new File(project.buildDir, 'liberty-plugin-config.xml').exists()) {
updatePluginXmlFile()
} else {
new File(project.buildDir, 'liberty-plugin-config.xml').withWriter { writer ->
def xmlDoc = new MarkupBuilder(writer)
xmlDoc.mkp.xmlDeclaration(version: "1.0", encoding: "UTF-8")
xmlDoc.'liberty-plugin-config'('version':'2.0') {
outputLibertyPropertiesToXml(xmlDoc, isExisting)
}
}
logger.info ("Creating Liberty plugin config info to ${project.buildDir}/liberty-plugin-config.xml.")
}
logger.info ("Adding Liberty plugin config info to ${project.buildDir}/liberty-plugin-config.xml.")
}
}

Expand Down Expand Up @@ -269,9 +342,14 @@ class InstallLibertyTask extends AbstractLibertyTask {
return result
}

protected void outputLibertyPropertiesToXml(MarkupBuilder xmlDoc) {
protected void outputLibertyPropertiesToXml(MarkupBuilder xmlDoc, boolean isExisting) {
xmlDoc.installDirectory (getInstallDir(project).toString())

// should only include assemblyArtifact and assemblyArchive if using an installation that was installed by our plugin
if (isExisting && ((project.liberty.installDir != null) || project.hasProperty('liberty.installDir'))) {
return
}

if (detachedCoords != null) {
String[] coords = detachedCoords.split(":")
xmlDoc.assemblyArtifact {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,10 @@ public class TestCreateConfigDirUpToDate extends AbstractIntegrationTest {
testFileMessageString = "\\build\\testBuilds\\test-create-config-dir-up-to-date\\src\\main\\liberty\\config\\test.txt has changed."
}

assert result.getOutput().contains(configDirMessageString)
assert result.getOutput().contains(testFileMessageString)
assert result.getOutput().contains(configDirMessageString) : "configDirMessageString not found in output: "+result.getOutput()
assert result.getOutput().contains(testFileMessageString) : "testFileMessageString not found in output: "+result.getOutput()

//Check updated file was copied to server directory
assert serverTestTextFile.text.contains('Test Comment 2')
assert serverTestTextFile.text.contains('Test Comment 2') : "Test Comment 2 not found in "+serverTestTextFile.text
}
}
Loading