diff --git a/jkube-kit/build/api/src/main/java/org/eclipse/jkube/kit/build/api/helper/BuildArgResolverUtil.java b/jkube-kit/build/api/src/main/java/org/eclipse/jkube/kit/build/api/helper/BuildArgResolverUtil.java
new file mode 100644
index 0000000000..89a93431ac
--- /dev/null
+++ b/jkube-kit/build/api/src/main/java/org/eclipse/jkube/kit/build/api/helper/BuildArgResolverUtil.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2019 Red Hat, Inc.
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at:
+ *
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Red Hat, Inc. - initial API and implementation
+ */
+package org.eclipse.jkube.kit.build.api.helper;
+
+import org.apache.commons.lang3.StringUtils;
+import org.eclipse.jkube.kit.common.JKubeConfiguration;
+import org.eclipse.jkube.kit.config.image.ImageConfiguration;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Properties;
+
+import static org.eclipse.jkube.kit.common.util.MapUtil.mergeMapsImmutable;
+
+public class BuildArgResolverUtil {
+ private static final String ARG_PREFIX = "docker.buildArg.";
+
+ private BuildArgResolverUtil() { }
+
+ /**
+ * Merges Docker Build Args in the following order (in decreasing order of precedence):
+ *
+ * - Build Args specified directly in ImageConfiguration
+ * - Build Args specified via System Properties
+ * - Build Args specified via Project Properties
+ * - Build Args specified via Plugin configuration
+ * - Docker Proxy Build Args detected from ~/.docker/config.json
+ *
+ * @param imageConfig ImageConfiguration for which Build Args would be resolved
+ * @param configuration {@link JKubeConfiguration} JKubeConfiguration
+ * @return a Map containing merged Build Args from all sources.
+ */
+ public static Map mergeBuildArgs(ImageConfiguration imageConfig, JKubeConfiguration configuration) {
+ Map buildArgsFromProjectProperties = addBuildArgsFromProperties(configuration.getProject().getProperties());
+ Map buildArgsFromSystemProperties = addBuildArgsFromProperties(System.getProperties());
+ Map buildArgsFromDockerConfig = addBuildArgsFromDockerConfig();
+
+ return mergeMapsImmutable(imageConfig.getBuild().getArgs(),
+ buildArgsFromSystemProperties,
+ buildArgsFromProjectProperties,
+ Optional.ofNullable(configuration.getBuildArgs()).orElse(Collections.emptyMap()),
+ buildArgsFromDockerConfig);
+ }
+
+ private static Map addBuildArgsFromProperties(Properties properties) {
+ Map buildArgs = new HashMap<>();
+ for (Object keyObj : properties.keySet()) {
+ String key = (String) keyObj;
+ if (key.startsWith(ARG_PREFIX)) {
+ String argKey = key.replaceFirst(ARG_PREFIX, "");
+ String value = properties.getProperty(key);
+
+ if (StringUtils.isNotBlank(value)) {
+ buildArgs.put(argKey, value);
+ }
+ }
+ }
+ return buildArgs;
+ }
+
+ private static Map addBuildArgsFromDockerConfig() {
+ final Map dockerConfig = DockerFileUtil.readDockerConfig();
+ if (dockerConfig == null) {
+ return Collections.emptyMap();
+ }
+
+ // add proxies
+ Map buildArgs = new HashMap<>();
+ if (dockerConfig.containsKey("proxies")) {
+ final Map proxies = (Map) dockerConfig.get("proxies");
+ if (proxies.containsKey("default")) {
+ final Map defaultProxyObj = (Map) proxies.get("default");
+ String[] proxyMapping = new String[] {
+ "httpProxy", "http_proxy",
+ "httpsProxy", "https_proxy",
+ "noProxy", "no_proxy",
+ "ftpProxy", "ftp_proxy"
+ };
+
+ for(int index = 0; index < proxyMapping.length; index += 2) {
+ if (defaultProxyObj.containsKey(proxyMapping[index])) {
+ buildArgs.put(ARG_PREFIX + proxyMapping[index+1], defaultProxyObj.get(proxyMapping[index]));
+ }
+ }
+ }
+ }
+ return buildArgs;
+ }
+}
diff --git a/jkube-kit/build/api/src/test/java/org/eclipse/jkube/kit/build/api/helper/BuildArgResolverUtilMergeBuildArgsTest.java b/jkube-kit/build/api/src/test/java/org/eclipse/jkube/kit/build/api/helper/BuildArgResolverUtilMergeBuildArgsTest.java
new file mode 100644
index 0000000000..ec3f6ca91c
--- /dev/null
+++ b/jkube-kit/build/api/src/test/java/org/eclipse/jkube/kit/build/api/helper/BuildArgResolverUtilMergeBuildArgsTest.java
@@ -0,0 +1,188 @@
+/*
+ * Copyright (c) 2019 Red Hat, Inc.
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at:
+ *
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Red Hat, Inc. - initial API and implementation
+ */
+package org.eclipse.jkube.kit.build.api.helper;
+
+import org.eclipse.jkube.kit.common.JKubeConfiguration;
+import org.eclipse.jkube.kit.common.JavaProject;
+import org.eclipse.jkube.kit.common.util.EnvUtil;
+import org.eclipse.jkube.kit.config.image.ImageConfiguration;
+import org.eclipse.jkube.kit.config.image.build.BuildConfiguration;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.io.TempDir;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
+
+class BuildArgResolverUtilMergeBuildArgsTest {
+ private ImageConfiguration imageConfiguration;
+ private JKubeConfiguration jKubeConfiguration;
+ private Properties projectProperties;
+ private Map buildArgFromPluginConfiguration;
+
+ @BeforeEach
+ void setUp() {
+ projectProperties = new Properties();
+ buildArgFromPluginConfiguration = new HashMap<>();
+ jKubeConfiguration = JKubeConfiguration.builder()
+ .project(JavaProject.builder()
+ .properties(projectProperties)
+ .build())
+ .buildArgs(buildArgFromPluginConfiguration)
+ .build();
+ imageConfiguration = ImageConfiguration.builder()
+ .name("image-name")
+ .build(BuildConfiguration.builder()
+ .build())
+ .build();
+ }
+
+ @Test
+ @DisplayName("build args in image config and project properties")
+ void whenBuildArgsFromImageConfigAndFromProjectProperties_shouldMergeBuildArgs() {
+ // Given
+ projectProperties.setProperty("docker.buildArg.VERSION", "latest");
+ projectProperties.setProperty("docker.buildArg.FULL_IMAGE", "busybox:latest");
+ Map buildArgImageConfiguration = new HashMap<>();
+ buildArgImageConfiguration.put("REPO_1", "docker.io/library");
+ buildArgImageConfiguration.put("IMAGE-1", "openjdk");
+ imageConfiguration = imageConfiguration.toBuilder()
+ .build(imageConfiguration.getBuild().toBuilder().args(buildArgImageConfiguration).build())
+ .build();
+
+ // When
+ Map mergedBuildArgs = BuildArgResolverUtil.mergeBuildArgs(imageConfiguration, jKubeConfiguration);
+
+ // Then
+ assertThat(mergedBuildArgs)
+ .containsEntry("VERSION", "latest")
+ .containsEntry("FULL_IMAGE", "busybox:latest")
+ .containsEntry("REPO_1", "docker.io/library")
+ .containsEntry("IMAGE-1", "openjdk");
+ }
+
+ @Test
+ @DisplayName("build args in image config, project properties, system properties, plugin configuration")
+ void fromAllSourcesWithDifferentKeys_shouldMergeBuildArgs() {
+ // Given
+ givenBuildArgsFromImageConfiguration("VERSION", "latest");
+ System.setProperty("docker.buildArg.IMAGE-1", "openjdk");
+ projectProperties.setProperty("docker.buildArg.REPO_1", "docker.io/library");
+ givenBuildArgsFromJKubeConfiguration("FULL_IMAGE", "busybox:latest");
+
+ // When
+ Map mergedBuildArgs = BuildArgResolverUtil.mergeBuildArgs(imageConfiguration, jKubeConfiguration);
+
+ // Then
+ assertThat(mergedBuildArgs)
+ .containsEntry("VERSION", "latest")
+ .containsEntry("FULL_IMAGE", "busybox:latest")
+ .containsEntry("REPO_1", "docker.io/library")
+ .containsEntry("IMAGE-1", "openjdk");
+ }
+
+ @Test
+ @DisplayName("build args in image config and system properties with same key, should throw exception")
+ void fromBuildConfigurationAndSystemPropertiesWithSameKey_shouldNotMergeBuildArgs() {
+ // Given
+ givenBuildArgsFromImageConfiguration("VERSION", "latest");
+ System.setProperty("docker.buildArg.VERSION", "1.0.0");
+
+ // When & Then
+ assertThatIllegalArgumentException()
+ .isThrownBy(() -> BuildArgResolverUtil.mergeBuildArgs(imageConfiguration, jKubeConfiguration))
+ .withMessage("Multiple entries with same key: VERSION=latest and VERSION=1.0.0");
+ }
+
+ @Test
+ @DisplayName("build args in image config and project properties with same key, should throw exception")
+ void fromBuildConfigurationAndProjectPropertiesWithSameKey_shouldNotMergeBuildArgs() {
+ // Given
+ givenBuildArgsFromImageConfiguration("VERSION", "latest");
+ projectProperties.setProperty("docker.buildArg.VERSION", "1.0.0");
+
+ // When & Then
+ assertThatIllegalArgumentException()
+ .isThrownBy(() -> BuildArgResolverUtil.mergeBuildArgs(imageConfiguration, jKubeConfiguration))
+ .withMessage("Multiple entries with same key: VERSION=latest and VERSION=1.0.0");
+ }
+
+ @Test
+ @DisplayName("build args in image config and plugin config with same key, should throw exception")
+ void fromBuildConfigurationAndJKubeConfigurationWithSameKey_shouldNotMergeBuildArgs() {
+ // Given
+ givenBuildArgsFromImageConfiguration("VERSION", "latest");
+ givenBuildArgsFromJKubeConfiguration("VERSION", "1.0.0");
+
+ // When & Then
+ assertThatIllegalArgumentException()
+ .isThrownBy(() -> BuildArgResolverUtil.mergeBuildArgs(imageConfiguration, jKubeConfiguration))
+ .withMessage("Multiple entries with same key: VERSION=latest and VERSION=1.0.0");
+ }
+
+ @Test
+ @DisplayName("should add proxy build args from ~/.docker/config.json")
+ void shouldAddBuildArgsFromDockerConfig(@TempDir File temporaryFolder) throws IOException {
+ try {
+ // Given
+ Path dockerConfig = temporaryFolder.toPath();
+ final Map env = Collections.singletonMap("DOCKER_CONFIG", dockerConfig.toFile().getAbsolutePath());
+ EnvUtil.overrideEnvGetter(env::get);
+ Files.write(dockerConfig.resolve("config.json"), ("{\"proxies\": {\"default\": {\n" +
+ " \"httpProxy\": \"http://proxy.example.com:3128\",\n" +
+ " \"httpsProxy\": \"https://proxy.example.com:3129\",\n" +
+ " \"noProxy\": \"*.test.example.com,.example.org,127.0.0.0/8\"\n" +
+ " }}}").getBytes());
+ // When
+ final Map mergedBuildArgs = BuildArgResolverUtil.mergeBuildArgs(imageConfiguration, jKubeConfiguration);
+ // Then
+ assertThat(mergedBuildArgs)
+ .containsEntry("docker.buildArg.http_proxy", "http://proxy.example.com:3128")
+ .containsEntry("docker.buildArg.https_proxy", "https://proxy.example.com:3129")
+ .containsEntry("docker.buildArg.no_proxy", "*.test.example.com,.example.org,127.0.0.0/8");
+ } finally {
+ EnvUtil.overrideEnvGetter(System::getenv);
+ }
+ }
+
+ private void givenBuildArgsFromImageConfiguration(String key, String value) {
+ imageConfiguration = imageConfiguration.toBuilder()
+ .build(BuildConfiguration.builder()
+ .args(
+ Collections.singletonMap(key, value))
+ .build())
+ .build();
+ }
+
+ private void givenBuildArgsFromJKubeConfiguration(String key, String value) {
+ buildArgFromPluginConfiguration.put(key, value);
+ }
+
+ @AfterEach
+ void clearSystemPropertiesUsedInTests() {
+ System.clearProperty("docker.buildArg.IMAGE-1");
+ System.clearProperty("docker.buildArg.VERSION");
+ }
+}
diff --git a/jkube-kit/build/service/docker/src/main/java/org/eclipse/jkube/kit/build/service/docker/BuildService.java b/jkube-kit/build/service/docker/src/main/java/org/eclipse/jkube/kit/build/service/docker/BuildService.java
index d4cc79d024..afe53693a6 100644
--- a/jkube-kit/build/service/docker/src/main/java/org/eclipse/jkube/kit/build/service/docker/BuildService.java
+++ b/jkube-kit/build/service/docker/src/main/java/org/eclipse/jkube/kit/build/service/docker/BuildService.java
@@ -16,18 +16,13 @@
import java.io.File;
import java.io.IOException;
import java.util.Collections;
-import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
-import java.util.Properties;
import java.util.LinkedList;
-import com.google.common.collect.ImmutableMap;
-
import org.eclipse.jkube.kit.common.JKubeConfiguration;
import org.eclipse.jkube.kit.build.api.helper.DockerFileUtil;
-import org.apache.commons.lang3.StringUtils;
import org.eclipse.jkube.kit.build.api.assembly.AssemblyManager;
import org.eclipse.jkube.kit.common.util.EnvUtil;
import org.eclipse.jkube.kit.build.service.docker.access.BuildOptions;
@@ -39,12 +34,11 @@
import org.eclipse.jkube.kit.config.image.build.BuildConfiguration;
import org.eclipse.jkube.kit.config.image.build.CleanupMode;
+import static org.eclipse.jkube.kit.build.api.helper.BuildArgResolverUtil.mergeBuildArgs;
import static org.eclipse.jkube.kit.build.api.helper.BuildUtil.extractBaseFromConfiguration;
public class BuildService {
- private static final String ARG_PREFIX = "docker.buildArg.";
-
private final DockerAccess docker;
private final QueryService queryService;
private final ArchiveService archiveService;
@@ -79,10 +73,6 @@ public void buildImage(ImageConfiguration imageConfig, ImagePullManager imagePul
buildImage(imageConfig, configuration, checkForNocache(imageConfig), mergedBuildArgs);
}
- static Map mergeBuildArgs(ImageConfiguration imageConfig, JKubeConfiguration configuration) {
- return prepareBuildArgs(addBuildArgs(configuration), imageConfig.getBuildConfiguration());
- }
-
public void tagImage(String imageName, ImageConfiguration imageConfig) throws DockerAccessException {
List tags = imageConfig.getBuildConfiguration().getTags();
@@ -165,14 +155,6 @@ protected void buildImage(ImageConfiguration imageConfig, JKubeConfiguration par
}
}
- private static Map prepareBuildArgs(Map buildArgs, BuildConfiguration buildConfig) {
- ImmutableMap.Builder builder = ImmutableMap.builder().putAll(buildArgs);
- if (buildConfig.getArgs() != null) {
- builder.putAll(buildConfig.getArgs());
- }
- return builder.build();
- }
-
private String getDockerfileName(BuildConfiguration buildConfig) {
if (buildConfig.isDockerFileMode()) {
return buildConfig.getDockerFile().getName();
@@ -187,64 +169,6 @@ private String doBuildImage(String imageName, File dockerArchive, BuildOptions o
return queryService.getImageId(imageName);
}
- private static Map addBuildArgs(JKubeConfiguration configuration) {
- Properties props = configuration.getProject().getProperties();
- Map buildArgsFromProject = addBuildArgsFromProperties(props);
- Map buildArgsFromSystem = addBuildArgsFromProperties(System.getProperties());
- Map buildArgsFromDockerConfig = addBuildArgsFromDockerConfig();
- return ImmutableMap.builder()
- .putAll(buildArgsFromDockerConfig)
- .putAll(Optional.ofNullable(configuration.getBuildArgs()).orElse(Collections.emptyMap()))
- .putAll(buildArgsFromProject)
- .putAll(buildArgsFromSystem)
- .build();
- }
-
- private static Map addBuildArgsFromProperties(Properties properties) {
- Map buildArgs = new HashMap<>();
- for (Object keyObj : properties.keySet()) {
- String key = (String) keyObj;
- if (key.startsWith(ARG_PREFIX)) {
- String argKey = key.replaceFirst(ARG_PREFIX, "");
- String value = properties.getProperty(key);
-
- if (StringUtils.isNotBlank(value)) {
- buildArgs.put(argKey, value);
- }
- }
- }
- return buildArgs;
- }
-
- private static Map addBuildArgsFromDockerConfig() {
- final Map dockerConfig = DockerFileUtil.readDockerConfig();
- if (dockerConfig == null) {
- return Collections.emptyMap();
- }
-
- // add proxies
- Map buildArgs = new HashMap<>();
- if (dockerConfig.containsKey("proxies")) {
- final Map proxies = (Map) dockerConfig.get("proxies");
- if (proxies.containsKey("default")) {
- final Map defaultProxyObj = (Map) proxies.get("default");
- String[] proxyMapping = new String[] {
- "httpProxy", "http_proxy",
- "httpsProxy", "https_proxy",
- "noProxy", "no_proxy",
- "ftpProxy", "ftp_proxy"
- };
-
- for(int index = 0; index < proxyMapping.length; index += 2) {
- if (defaultProxyObj.containsKey(proxyMapping[index])) {
- buildArgs.put(ARG_PREFIX + proxyMapping[index+1], defaultProxyObj.get(proxyMapping[index]));
- }
- }
- }
- }
- return buildArgs;
- }
-
private void autoPullBaseImage(ImageConfiguration imageConfig, ImagePullManager imagePullManager,
JKubeConfiguration configuration, Map mergedBuildArgs)
throws IOException {
diff --git a/jkube-kit/build/service/docker/src/test/java/org/eclipse/jkube/kit/build/service/docker/BuildServiceTest.java b/jkube-kit/build/service/docker/src/test/java/org/eclipse/jkube/kit/build/service/docker/BuildServiceTest.java
index fff6800585..1cf0f05bb3 100644
--- a/jkube-kit/build/service/docker/src/test/java/org/eclipse/jkube/kit/build/service/docker/BuildServiceTest.java
+++ b/jkube-kit/build/service/docker/src/test/java/org/eclipse/jkube/kit/build/service/docker/BuildServiceTest.java
@@ -107,126 +107,6 @@ void tagImage_whenValidImageConfigurationProvided_shouldTagImage() throws Docker
.tag("image-name", "image-name:latest", true);
}
- @Test
- void mergeBuildArgs_whenBuildArgsFromImageConfigAndFromProjectProperties_shouldMergeBuildArgs() {
- // Given
- Properties props = new Properties();
- props.setProperty("docker.buildArg.VERSION", "latest");
- props.setProperty("docker.buildArg.FULL_IMAGE", "busybox:latest");
- when(mockedJKubeConfiguration.getProject().getProperties()).thenReturn(props);
-
- Map imgConfigBuildArg = new HashMap<>();
- imgConfigBuildArg.put("REPO_1", "docker.io/library");
- imgConfigBuildArg.put("IMAGE-1", "openjdk");
- imageConfiguration = ImageConfiguration.builder()
- .name("image-name")
- .build(BuildConfiguration.builder()
- .args(imgConfigBuildArg)
- .build())
- .build();
-
- // When
- Map mergedBuildArgs = BuildService.mergeBuildArgs(imageConfiguration, mockedJKubeConfiguration);
-
- // Then
- assertThat(mergedBuildArgs)
- .containsEntry("VERSION", "latest")
- .containsEntry("FULL_IMAGE", "busybox:latest")
- .containsEntry("REPO_1", "docker.io/library")
- .containsEntry("IMAGE-1", "openjdk");
- }
-
- @Nested
- @DisplayName("mergeBuildArgs with BuildArgs")
- class MergeBuildArgs {
- @Test
- void fromAllSourcesWithDifferentKeys_shouldMergeBuildArgs() {
- // Given
- givenBuildArgsFromImageConfiguration("VERSION", "latest");
- givenBuildArgsFromSystemProperties("docker.buildArg.IMAGE-1", "openjdk");
- givenBuildArgsFromProjectProperties("docker.buildArg.REPO_1", "docker.io/library");
- givenBuildArgsFromJKubeConfiguration("FULL_IMAGE", "busybox:latest");
-
- // When
- Map mergedBuildArgs = BuildService.mergeBuildArgs(imageConfiguration, mockedJKubeConfiguration);
-
- // Then
- assertThat(mergedBuildArgs)
- .containsEntry("VERSION", "latest")
- .containsEntry("FULL_IMAGE", "busybox:latest")
- .containsEntry("REPO_1", "docker.io/library")
- .containsEntry("IMAGE-1", "openjdk");
- }
-
- @Test
- void fromBuildConfigurationAndSystemPropertiesWithSameKey_shouldNotMergeBuildArgs() {
- // Given
- givenBuildArgsFromImageConfiguration("VERSION", "latest");
- givenBuildArgsFromSystemProperties("docker.buildArg.VERSION", "1.0.0");
-
- // When & Then
- assertThatIllegalArgumentException()
- .isThrownBy(() -> BuildService.mergeBuildArgs(imageConfiguration, mockedJKubeConfiguration))
- .withMessage("Multiple entries with same key: VERSION=latest and VERSION=1.0.0");
- }
-
- @Test
- void fromBuildConfigurationAndProjectPropertiesWithSameKey_shouldNotMergeBuildArgs() {
- // Given
- givenBuildArgsFromImageConfiguration("VERSION", "latest");
- givenBuildArgsFromProjectProperties("docker.buildArg.VERSION", "1.0.0");
-
- // When & Then
- assertThatIllegalArgumentException()
- .isThrownBy(() -> BuildService.mergeBuildArgs(imageConfiguration, mockedJKubeConfiguration))
- .withMessage("Multiple entries with same key: VERSION=latest and VERSION=1.0.0");
- }
-
- @Test
- void fromBuildConfigurationAndJKubeConfigurationWithSameKey_shouldNotMergeBuildArgs() {
- // Given
- givenBuildArgsFromImageConfiguration("VERSION", "latest");
- givenBuildArgsFromJKubeConfiguration("VERSION", "1.0.0");
-
- // When & Then
- assertThatIllegalArgumentException()
- .isThrownBy(() -> BuildService.mergeBuildArgs(imageConfiguration, mockedJKubeConfiguration))
- .withMessage("Multiple entries with same key: VERSION=latest and VERSION=1.0.0");
- }
-
- private void givenBuildArgsFromImageConfiguration(String key, String value) {
- imageConfiguration = ImageConfiguration.builder()
- .name("image-name")
- .build(BuildConfiguration.builder()
- .args(
- Collections.singletonMap(key, value))
- .build())
- .build();
- }
-
- private void givenBuildArgsFromSystemProperties(String key, String value) {
- System.setProperty(key, value);
- }
-
- private void givenBuildArgsFromProjectProperties(String key, String value) {
- Properties props = new Properties();
- props.setProperty(key, value);
- when(mockedJKubeConfiguration.getProject().getProperties())
- .thenReturn(props);
- }
-
- private void givenBuildArgsFromJKubeConfiguration(String key, String value) {
- when(mockedJKubeConfiguration.getBuildArgs())
- .thenReturn(Collections.singletonMap(key, value));
- }
-
- @AfterEach
- void clearSystemPropertiesUsedInTests() {
- System.clearProperty("docker.buildArg.IMAGE-1");
- System.clearProperty("docker.buildArg.VERSION");
- }
- }
-
@Test
void buildImage_whenMultiStageDockerfileWithBuildArgs_shouldPrepullImages() throws IOException {
// Given
diff --git a/jkube-kit/common/src/main/java/org/eclipse/jkube/kit/common/util/MapUtil.java b/jkube-kit/common/src/main/java/org/eclipse/jkube/kit/common/util/MapUtil.java
index f2657f2cea..238e86c010 100644
--- a/jkube-kit/common/src/main/java/org/eclipse/jkube/kit/common/util/MapUtil.java
+++ b/jkube-kit/common/src/main/java/org/eclipse/jkube/kit/common/util/MapUtil.java
@@ -42,6 +42,32 @@ public static void mergeIfAbsent(Map map, Map to
}
}
+ /**
+ * Returns a new map with all the entries of first map with rest map entries. It throws IllegalArgumentException
+ * when it encounters conflicting keys
+ *
+ * @param maps var arg parameter of maps to be merged
+ * @return merged map
+ * @param key type
+ * @param value type
+ * @throws IllegalArgumentException when multiple entries with same key are found
+ */
+ @SafeVarargs
+ public static Map mergeMapsImmutable(Map... maps) {
+ Map answer = new HashMap<>();
+ for (int i = maps.length-1; i >= 0; i--) {
+ if (maps[i] != null) {
+ for (Map.Entry e : maps[i].entrySet()) {
+ if (answer.containsKey(e.getKey())) {
+ throw new IllegalArgumentException(String.format("Multiple entries with same key: %s=%s and %s=%s", e.getKey(), e.getValue(), e.getKey(), answer.get(e.getKey())));
+ }
+ answer.put(e.getKey(), e.getValue());
+ }
+ }
+ }
+ return answer;
+ }
+
/**
* Returns a new map with all the entries of first map with rest map entries which don't override map1.
*
diff --git a/jkube-kit/common/src/test/java/org/eclipse/jkube/kit/common/util/MapUtilTest.java b/jkube-kit/common/src/test/java/org/eclipse/jkube/kit/common/util/MapUtilTest.java
index 999fc21306..1000e052f1 100644
--- a/jkube-kit/common/src/test/java/org/eclipse/jkube/kit/common/util/MapUtilTest.java
+++ b/jkube-kit/common/src/test/java/org/eclipse/jkube/kit/common/util/MapUtilTest.java
@@ -19,12 +19,16 @@
import java.util.Map;
import org.assertj.core.api.InstanceOfAssertFactories;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
import static org.assertj.core.api.Assertions.entry;
import static org.eclipse.jkube.kit.common.util.MapUtil.getFlattenedMap;
import static org.eclipse.jkube.kit.common.util.MapUtil.getNestedMap;
+import static org.eclipse.jkube.kit.common.util.MapUtil.mergeMapsImmutable;
import static org.junit.jupiter.api.Assertions.assertThrows;
/**
@@ -136,6 +140,39 @@ void getNestedMap_withInvalidFlattenedMap_shouldThrowNodeOverlapsException() {
assertThat(result).hasMessage("The provided input Map is invalid (node overlaps with key)");
}
+ @Nested
+ class MergeMapsImmutable {
+ @Test
+ @DisplayName("different keys present in maps, then merge maps")
+ void whenNoConflictingKeysProvided_thenMergeMaps() {
+ // Given
+ Map m1 = createMap("foo", "bar");
+ Map m2 = createMap("BAR", "FOO");
+
+ // When
+ Map result = mergeMapsImmutable(m1, m2);
+
+ // Then
+ assertThat(result)
+ .containsEntry("foo", "bar")
+ .containsEntry("BAR", "FOO");
+ }
+
+ @Test
+ @DisplayName("same keys present in maps, then throw exception")
+ void whenConflictingKeysProvided_thenThrowException() {
+ // Given
+ Map m1 = createMap("foo", "bar");
+ Map m2 = createMap("foo", "FOO");
+
+ // When + Then
+ assertThatIllegalArgumentException()
+ .isThrownBy(() -> MapUtil.mergeMapsImmutable(m1, m2, null))
+ .withMessage("Multiple entries with same key: foo=bar and foo=FOO");
+ }
+ }
+
+
private Map createMap(String ... args) {
Map ret = new LinkedHashMap<>();
for (int i = 0; i < args.length; i+=2) {