diff --git a/spring-cloud-release-tools-core/src/main/java/org/springframework/cloud/release/internal/project/ProjectBuilder.java b/spring-cloud-release-tools-core/src/main/java/org/springframework/cloud/release/internal/project/ProjectBuilder.java index 6880c859..6e82db82 100644 --- a/spring-cloud-release-tools-core/src/main/java/org/springframework/cloud/release/internal/project/ProjectBuilder.java +++ b/spring-cloud-release-tools-core/src/main/java/org/springframework/cloud/release/internal/project/ProjectBuilder.java @@ -8,8 +8,14 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.SimpleFileVisitor; import java.nio.file.attribute.BasicFileAttributes; +import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; +import java.util.Queue; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Collectors; import org.slf4j.Logger; @@ -17,6 +23,7 @@ import org.slf4j.LoggerFactory; import org.springframework.cloud.release.internal.ReleaserProperties; import org.springframework.cloud.release.internal.pom.ProjectPomUpdater; import org.springframework.cloud.release.internal.pom.ProjectVersion; +import org.springframework.util.StringUtils; /** * @author Marcin Grzejszczak @@ -102,14 +109,39 @@ public class ProjectBuilder { this.pomUpdater.updatePomsForRootVersion(dir, version); } + /** + * We need to insert the system properties as a list of -Dkey=value entries + * instead of just pasting the String that contains these values + */ private String[] substituteSystemProps(String... commands) { - return Arrays.stream(commands).map(s -> { - if (s.contains(ReleaserProperties.Maven.SYSTEM_PROPS_PLACEHOLDER)) { - return s.replace(ReleaserProperties.Maven.SYSTEM_PROPS_PLACEHOLDER, - this.properties.getMaven().getSystemProperties()); + boolean containsSystemProps = this.properties.getMaven().getSystemProperties().contains("-D"); + String[] splitSystemProps = StringUtils.tokenizeToStringArray(this.properties.getMaven() + .getSystemProperties(), "-D"); + String[] systemPropsWithPrefix = containsSystemProps ? Arrays.stream(splitSystemProps) + .map(s -> "-D" + s) + .collect(Collectors.toList()) + .toArray(new String[splitSystemProps.length]) : splitSystemProps; + final AtomicInteger index = new AtomicInteger(-1); + for (int i = 0; i < commands.length; i++) { + if (commands[i].contains(ReleaserProperties.Maven.SYSTEM_PROPS_PLACEHOLDER)) { + index.set(i); + break; } - return s; - }).collect(Collectors.toList()).toArray(new String[commands.length]); + } + List commandsList = new ArrayList<>(Arrays.asList(commands)); + List systemPropsList = Arrays.asList(systemPropsWithPrefix); + if (index.get() != -1) { + commandsList.remove(index.get()); + if (index.get() >= commandsList.size()) { + commandsList.addAll(systemPropsList); + } else { + // we need to reverse to set the objects in the same order as passed in the prop + List reversedSystemProps = new ArrayList<>(systemPropsList); + Collections.reverse(reversedSystemProps); + reversedSystemProps.forEach(s -> commandsList.add(index.get(), s)); + } + } + return commandsList.toArray(new String[commandsList.size()]); } } @@ -125,7 +157,7 @@ class ProcessExecutor { void runCommand(String[] commands, long waitTimeInMinutes) { try { String workingDir = this.properties.getWorkingDir(); - log.info("Will run the build via {} and wait for result for [{}] minutes", commands, waitTimeInMinutes); + log.debug("Will run the build via {} and wait for result for [{}] minutes", commands, waitTimeInMinutes); ProcessBuilder builder = builder(commands, workingDir); Process process = startProcess(builder); boolean finished = process.waitFor(waitTimeInMinutes, TimeUnit.MINUTES); diff --git a/spring-cloud-release-tools-core/src/test/java/org/springframework/cloud/release/internal/project/ProjectBuilderTests.java b/spring-cloud-release-tools-core/src/test/java/org/springframework/cloud/release/internal/project/ProjectBuilderTests.java index 5647eb23..d73d2e3e 100644 --- a/spring-cloud-release-tools-core/src/test/java/org/springframework/cloud/release/internal/project/ProjectBuilderTests.java +++ b/spring-cloud-release-tools-core/src/test/java/org/springframework/cloud/release/internal/project/ProjectBuilderTests.java @@ -58,14 +58,42 @@ public class ProjectBuilderTests { public void should_successfully_execute_a_command_when_system_props_placeholder_is_present() throws Exception { ReleaserProperties properties = new ReleaserProperties(); properties.getMaven().setBuildCommand("echo {{systemProps}}"); - properties.getMaven().setSystemProperties("hello world"); + properties.getMaven().setSystemProperties("-Dhello=world -Dfoo=bar"); properties.setWorkingDir(tmpFile("/builder/resolved").getPath()); ProjectBuilder builder = new ProjectBuilder(properties, executor(properties)); builder.build(); then(asString(tmpFile("/builder/resolved/resolved.log"))) - .contains("hello world"); + .contains("-Dhello=world -Dfoo=bar"); + } + + @Test + public void should_successfully_execute_a_command_when_system_props_placeholder_is_present_without_system_props() throws Exception { + ReleaserProperties properties = new ReleaserProperties(); + properties.getMaven().setBuildCommand("echo {{systemProps}}"); + properties.getMaven().setSystemProperties("hello=world foo=bar"); + properties.setWorkingDir(tmpFile("/builder/resolved").getPath()); + ProjectBuilder builder = new ProjectBuilder(properties, executor(properties)); + + builder.build(); + + then(asString(tmpFile("/builder/resolved/resolved.log"))) + .contains("hello=world foo=bar"); + } + + @Test + public void should_successfully_execute_a_command_when_system_props_placeholder_is_present_inside_command() throws Exception { + ReleaserProperties properties = new ReleaserProperties(); + properties.getMaven().setBuildCommand("echo {{systemProps}} bar"); + properties.getMaven().setSystemProperties("-Dhello=world -Dfoo=bar"); + properties.setWorkingDir(tmpFile("/builder/resolved").getPath()); + ProjectBuilder builder = new ProjectBuilder(properties, executor(properties)); + + builder.build(); + + then(asString(tmpFile("/builder/resolved/resolved.log"))) + .contains("-Dhello=world -Dfoo=bar bar"); } @Test @@ -145,8 +173,8 @@ public class ProjectBuilderTests { @Test public void should_successfully_execute_a_publish_docs_command_with_sys_props_placeholder() throws Exception { ReleaserProperties properties = new ReleaserProperties(); - properties.getMaven().setPublishDocsCommands(new String[] { "echo {{systemProps}}1", "echo {{systemProps}}2" }); - properties.getMaven().setSystemProperties("hello world"); + properties.getMaven().setPublishDocsCommands(new String[] { "echo {{systemProps}} 1", "echo {{systemProps}} 2" }); + properties.getMaven().setSystemProperties("-Dhello=world -Dfoo=bar"); properties.setWorkingDir(tmpFile("/builder/resolved").getPath()); TestProcessExecutor executor = executor(properties); ProjectBuilder builder = new ProjectBuilder(properties, executor); @@ -154,10 +182,10 @@ public class ProjectBuilderTests { builder.publishDocs(""); then(asString(tmpFile("/builder/resolved/resolved.log"))) - .contains("hello world2"); + .contains("-Dhello=world -Dfoo=bar 2"); then(outputCapture.toString()) - .contains("Will run the build via [echo, hello world1]") - .contains("Will run the build via [echo, hello world2]"); + .contains("Will run the build via [echo, -Dhello=world, -Dfoo=bar, 1]") + .contains("Will run the build via [echo, -Dhello=world, -Dfoo=bar, 2]"); then(executor.counter).isEqualTo(2); }