diff --git a/src/main/java/io/fabric8/maven/docker/service/BuildXService.java b/src/main/java/io/fabric8/maven/docker/service/BuildXService.java index 1f63cd3e9..6a389521f 100644 --- a/src/main/java/io/fabric8/maven/docker/service/BuildXService.java +++ b/src/main/java/io/fabric8/maven/docker/service/BuildXService.java @@ -5,36 +5,17 @@ import io.fabric8.maven.docker.access.util.ExternalCommand; import io.fabric8.maven.docker.assembly.BuildDirs; import io.fabric8.maven.docker.assembly.DockerAssemblyManager; -import io.fabric8.maven.docker.config.AttestationConfiguration; -import io.fabric8.maven.docker.config.BuildImageConfiguration; -import io.fabric8.maven.docker.config.BuildXConfiguration; -import io.fabric8.maven.docker.config.ConfigHelper; -import io.fabric8.maven.docker.config.ImageConfiguration; -import io.fabric8.maven.docker.config.SecretConfiguration; +import io.fabric8.maven.docker.config.*; import io.fabric8.maven.docker.util.EnvUtil; import io.fabric8.maven.docker.util.ImageName; import io.fabric8.maven.docker.util.Logger; import io.fabric8.maven.docker.util.ProjectPaths; import org.apache.maven.plugin.MojoExecutionException; -import java.io.BufferedReader; -import java.io.BufferedWriter; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; +import java.io.*; import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.nio.file.StandardCopyOption; -import java.nio.file.StandardOpenOption; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Optional; +import java.nio.file.*; +import java.util.*; import java.util.concurrent.CompletableFuture; import java.util.function.BiConsumer; import java.util.function.Consumer; @@ -74,7 +55,6 @@ protected void useBuilder(ProjectPaths projectPaths, ImageConfiguration imag List buildX = new ArrayList<>(Arrays.asList(DOCKER, "--config", configPath.toString(), "buildx")); if (!isDockerBuildXWorkingWithOverriddenConfig(configPath)) { logger.debug("Detected current version of BuildX not working with --config override"); - logger.debug("Copying BuildX binary to " + configPath); copyBuildXToConfigPathIfBuildXBinaryInDefaultDockerConfig(configPath); } @@ -90,10 +70,12 @@ protected void useBuilder(ProjectPaths projectPaths, ImageConfiguration imag private void copyBuildXToConfigPathIfBuildXBinaryInDefaultDockerConfig(Path configPath) { try { - File buildXInUserHomeDockerConfig = Paths.get(EnvUtil.getUserHome(), ".docker/cli-plugins/docker-buildx").toFile(); + String dockerBuildxExecutableName = "docker-buildx" + (EnvUtil.isWindows()?".exe":""); + File buildXInUserHomeDockerConfig = Paths.get(EnvUtil.getUserHome(), ".docker/cli-plugins/" + dockerBuildxExecutableName).toFile(); Files.createDirectory(configPath.resolve("cli-plugins")); if (buildXInUserHomeDockerConfig.exists() && buildXInUserHomeDockerConfig.isFile()) { - Files.copy(buildXInUserHomeDockerConfig.toPath(), configPath.resolve("cli-plugins").resolve("docker-buildx"), StandardCopyOption.COPY_ATTRIBUTES); + Files.copy(buildXInUserHomeDockerConfig.toPath(), configPath.resolve("cli-plugins").resolve(dockerBuildxExecutableName), StandardCopyOption.COPY_ATTRIBUTES); + logger.debug("Copying BuildX binary to " + configPath); } } catch (IOException exception) { logger.debug(exception.getMessage()); diff --git a/src/test/java/io/fabric8/maven/docker/service/BuildXServiceTest.java b/src/test/java/io/fabric8/maven/docker/service/BuildXServiceTest.java index 5e35792da..438ffe424 100644 --- a/src/test/java/io/fabric8/maven/docker/service/BuildXServiceTest.java +++ b/src/test/java/io/fabric8/maven/docker/service/BuildXServiceTest.java @@ -1,57 +1,43 @@ package io.fabric8.maven.docker.service; -import io.fabric8.maven.docker.util.ImageName; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.io.File; -import java.nio.file.Paths; - import io.fabric8.maven.docker.access.AuthConfig; -import java.util.function.BiConsumer; - +import io.fabric8.maven.docker.access.AuthConfigList; +import io.fabric8.maven.docker.access.DockerAccess; +import io.fabric8.maven.docker.assembly.DockerAssemblyManager; +import io.fabric8.maven.docker.config.BuildImageConfiguration; +import io.fabric8.maven.docker.config.BuildXConfiguration; +import io.fabric8.maven.docker.config.ImageConfiguration; import io.fabric8.maven.docker.util.EnvUtil; +import io.fabric8.maven.docker.util.ImageName; +import io.fabric8.maven.docker.util.Logger; +import io.fabric8.maven.docker.util.ProjectPaths; import org.apache.maven.plugin.MojoExecutionException; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; - import org.junit.jupiter.api.io.TempDir; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; -import org.mockito.ArgumentCaptor; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.MockedConstruction; -import org.mockito.MockedStatic; -import org.mockito.Spy; -import org.mockito.Mockito; -import org.mockito.quality.Strictness; +import org.mockito.*; import org.mockito.junit.jupiter.MockitoExtension; import org.mockito.junit.jupiter.MockitoSettings; +import org.mockito.quality.Strictness; -import io.fabric8.maven.docker.access.DockerAccess; -import io.fabric8.maven.docker.access.AuthConfigList; -import io.fabric8.maven.docker.assembly.DockerAssemblyManager; -import io.fabric8.maven.docker.util.Logger; -import io.fabric8.maven.docker.util.ProjectPaths; -import io.fabric8.maven.docker.config.BuildXConfiguration; -import io.fabric8.maven.docker.config.BuildImageConfiguration; -import io.fabric8.maven.docker.config.ImageConfiguration; +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.function.BiConsumer; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.mockConstruction; -import static org.mockito.Mockito.mockStatic; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; @ExtendWith(MockitoExtension.class) @MockitoSettings(strictness = Strictness.WARN) @@ -238,10 +224,11 @@ void useBuilder_whenConfiguredRegistryAbsentInDockerRegistry_thenAddConfigOption assertEquals(Arrays.asList("docker", "--config", temporaryFolder.getAbsolutePath(), "buildx"), buildXArgCaptor.getValue()); } - @Test - void useBuilder_whenDockerBuildXIncompatibleWithConfigOverride_thenCopyBuildXBinaryToTemporaryConfig() throws IOException, MojoExecutionException { + @ParameterizedTest + @ValueSource(booleans = {true, false}) + void useBuilder_whenDockerBuildXIncompatibleWithConfigOverride_thenCopyBuildXBinaryToTemporaryConfig(boolean isWindows) throws IOException, MojoExecutionException { try (MockedStatic envUtilMockedStatic = mockStatic(EnvUtil.class); - MockedConstruction ignore = mockConstruction(BuildXService.BuildXListWithConfigCommand.class, (mock, ctx) -> { + MockedConstruction ignore = mockConstruction(BuildXService.BuildXListWithConfigCommand.class, (mock, ctx) -> { when(mock.isSuccessFul()).thenReturn(false); })) { // Given @@ -249,9 +236,12 @@ void useBuilder_whenDockerBuildXIncompatibleWithConfigOverride_thenCopyBuildXBin Files.createDirectory(configDirPath); Files.createDirectory(temporaryFolder.toPath().resolve(".docker")); Files.createDirectory(temporaryFolder.toPath().resolve(".docker").resolve("cli-plugins")); - Files.createFile(temporaryFolder.toPath().resolve(".docker").resolve("cli-plugins").resolve("docker-buildx")); + final String buildxExecutableFilename = "docker-buildx" + (isWindows ? ".exe" : ""); + Files.createFile(temporaryFolder.toPath().resolve(".docker").resolve("cli-plugins").resolve(buildxExecutableFilename)); envUtilMockedStatic.when(EnvUtil::getUserHome).thenReturn(temporaryFolder.getAbsolutePath()); + envUtilMockedStatic.when(EnvUtil::isWindows).thenReturn(isWindows); BuildXService.Builder builder = Mockito.mock(BuildXService.Builder.class); + givenAnImageConfiguration("linux/arm46", "linux/amd64"); // When @@ -259,7 +249,7 @@ void useBuilder_whenDockerBuildXIncompatibleWithConfigOverride_thenCopyBuildXBin // Then assertTrue(configDirPath.resolve("cli-plugins").toFile().exists()); - assertTrue(configDirPath.resolve("cli-plugins").resolve("docker-buildx").toFile().exists()); + assertTrue(configDirPath.resolve("cli-plugins").resolve(buildxExecutableFilename).toFile().exists()); verify(logger).debug("Detected current version of BuildX not working with --config override"); verify(logger).debug("Copying BuildX binary to " + temporaryFolder.toPath().resolve("docker-state-dir")); }