diff --git a/CHANGELOG.md b/CHANGELOG.md index 2c341b4..4c356e2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,11 +1,16 @@ +# 2.0.1 +* Improve matching in ``DockerfileCOPYParentsEmulator`` #134 + * Now should properly handle ``./`` + # 2.0.0 * Changed ignore backend to utilize [JGit](https://github.com/eclipse-jgit/jgit) * This should now behave exactly like a ``.gitignore`` * Overall performance should be a lot faster * Make it possible to modify transferred files -* Provide an option to emulate [``COPY --parents``](https://docs.docker.com/reference/dockerfile/#copy---parents) (which is currently not supported by Docker out of the box) +* Provide an option to emulate [``COPY --parents``](https://docs.docker.com/reference/dockerfile/#copy---parents) using ``DockerfileCOPYParentsEmulator`` (which is currently not supported by Docker out of the box) * This option is required to utilize Docker's cache properly ```docker + # syntax=docker/dockerfile:1-labs # ... # Copy & Cache wrapper diff --git a/README.md b/README.md index 60e9396..651c117 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ A re-implementation of [Testcontainers Image-Builder](https://java.testcontainer * Makes logger non generic and therefore controllable * Some general code cleanup and performance improvements -A common use case - that can also be seen [inside the demo](./testcontainers-advanced-imagebuilder-demo/src/main/java/software/xdev/Application.java) - is for creating an image - used in e.g. Integration tests - for an application that is also inside the same repo. +For more details have a look at [the demo](./testcontainers-advanced-imagebuilder-demo/src/main/java/software/xdev/Application.java).
The demo showcases how an image for another application in the same repo can be built. ## Installation [Installation guide for the latest release](https://github.com/xdev-software/testcontainers-advanced-imagebuilder/releases/latest#Installation) diff --git a/pom.xml b/pom.xml index d02f22e..622fc4b 100644 --- a/pom.xml +++ b/pom.xml @@ -46,7 +46,7 @@ com.puppycrawl.tools checkstyle - 10.25.0 + 10.25.1 diff --git a/testcontainers-advanced-imagebuilder-demo/Dockerfile b/testcontainers-advanced-imagebuilder-demo/Dockerfile index 57e00b0..4cd5317 100644 --- a/testcontainers-advanced-imagebuilder-demo/Dockerfile +++ b/testcontainers-advanced-imagebuilder-demo/Dockerfile @@ -3,7 +3,7 @@ ARG JAVA_VERSION=21 FROM eclipse-temurin:$JAVA_VERSION-jdk-alpine AS build-env -RUN apk add --no-cache git bash +RUN apk add --no-cache bash WORKDIR /build @@ -21,13 +21,6 @@ RUN ${MAVEN_GO_OFFLINE_COMMAND} # Copying all other files COPY . ./ -# A valid Git repo is required for the build -RUN git config --global user.email "dynamic@build.local" \ - && git config --global user.name "Dynamic Build" \ - && git init --initial-branch=dynamically-built-tcst \ - && git add . \ - && git commit -m "Init commit" - ARG MAVEN_BUILD_COMMAND='./mvnw -B clean package -pl "testcontainers-advanced-imagebuilder-dummy-app" -am -T2C -Dmaven.test.skip' RUN echo "Executing '$MAVEN_BUILD_COMMAND'" RUN ${MAVEN_BUILD_COMMAND} diff --git a/testcontainers-advanced-imagebuilder/pom.xml b/testcontainers-advanced-imagebuilder/pom.xml index a669002..3dd5900 100644 --- a/testcontainers-advanced-imagebuilder/pom.xml +++ b/testcontainers-advanced-imagebuilder/pom.xml @@ -56,7 +56,7 @@ org.testcontainers testcontainers - 1.21.1 + 1.21.2 @@ -205,7 +205,7 @@ org.codehaus.mojo flatten-maven-plugin - 1.7.0 + 1.7.1 ossrh @@ -267,7 +267,7 @@ com.puppycrawl.tools checkstyle - 10.25.0 + 10.25.1 diff --git a/testcontainers-advanced-imagebuilder/src/main/java/software/xdev/testcontainers/imagebuilder/compat/DockerfileCOPYParentsEmulator.java b/testcontainers-advanced-imagebuilder/src/main/java/software/xdev/testcontainers/imagebuilder/compat/DockerfileCOPYParentsEmulator.java index ddb3b20..e6482c5 100644 --- a/testcontainers-advanced-imagebuilder/src/main/java/software/xdev/testcontainers/imagebuilder/compat/DockerfileCOPYParentsEmulator.java +++ b/testcontainers-advanced-imagebuilder/src/main/java/software/xdev/testcontainers/imagebuilder/compat/DockerfileCOPYParentsEmulator.java @@ -18,9 +18,11 @@ import java.util.List; import java.util.Map; import java.util.Set; +import java.util.regex.Pattern; import java.util.stream.Stream; -import software.xdev.testcontainers.imagebuilder.glob.GlobMatcher; +import software.xdev.testcontainers.imagebuilder.jgit.errors.InvalidPatternException; +import software.xdev.testcontainers.imagebuilder.jgit.ignore.internal.Strings; import software.xdev.testcontainers.imagebuilder.transfer.DockerFileLineModifier; @@ -118,9 +120,9 @@ protected Stream handleLine(final String line, final Set relativ return Stream.of(args) .limit((long)args.length - (isLastArg ? 1 : 0)) .flatMap(source -> { - if(!source.contains("*") && !source.contains("/")) + if(!source.contains("*")) { - return Stream.of(Map.entry(source, targetPathFinal)); + return Stream.of(Map.entry(source, targetPathFinalForRelative + removeRelativeStart(source))); } final GlobMatcher matcher = new GlobMatcher(source); @@ -133,4 +135,38 @@ protected Stream handleLine(final String line, final Set relativ + (!lineAfterArgsFinal.isEmpty() ? " " + lineAfterArgsFinal : "") + " " + e.getValue()); } + + protected static String removeRelativeStart(final String path) + { + return path.startsWith("./") ? path.substring(2) : path; + } + + public static class GlobMatcher + { + protected final Pattern pattern; + + public GlobMatcher(final String pattern) + { + try + { + this.pattern = Pattern.compile("\\/?" + Strings.convertGlob(removeRelativeStart(pattern))); + } + catch(final InvalidPatternException e) + { + throw new IllegalArgumentException(e); + } + } + + @SuppressWarnings("checkstyle:FinalParameters") + protected String correctPathForMatching(String path) + { + path = removeRelativeStart(path); + return path.startsWith("/") ? path : ("/" + path); + } + + public boolean matches(final String path) + { + return this.pattern.matcher(this.correctPathForMatching(path)).matches(); + } + } } diff --git a/testcontainers-advanced-imagebuilder/src/main/java/software/xdev/testcontainers/imagebuilder/glob/GlobMatcher.java b/testcontainers-advanced-imagebuilder/src/main/java/software/xdev/testcontainers/imagebuilder/glob/GlobMatcher.java deleted file mode 100644 index 617c24e..0000000 --- a/testcontainers-advanced-imagebuilder/src/main/java/software/xdev/testcontainers/imagebuilder/glob/GlobMatcher.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright © 2024 XDEV Software (https://xdev.software) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package software.xdev.testcontainers.imagebuilder.glob; - -import java.util.regex.Pattern; - -import software.xdev.testcontainers.imagebuilder.jgit.errors.InvalidPatternException; -import software.xdev.testcontainers.imagebuilder.jgit.ignore.internal.Strings; - - -/** - * A simple implementation of GlobMatcher that utilizes JGit's {@link Strings#convertGlob(String)} - */ -public class GlobMatcher -{ - protected final Pattern pattern; - - public GlobMatcher(final String pattern) - { - try - { - this.pattern = Pattern.compile("\\/?" + Strings.convertGlob(pattern)); - } - catch(final InvalidPatternException e) - { - throw new IllegalArgumentException(e); - } - } - - protected String correctPathForMatching(final String path) - { - return path.startsWith("/") ? path : ("/" + path); - } - - public boolean matches(final String path) - { - return this.pattern.matcher(this.correctPathForMatching(path)).matches(); - } -} diff --git a/testcontainers-advanced-imagebuilder/src/test/java/software/xdev/testcontainers/imagebuilder/compat/DockerfileCOPYParentsEmulatorTest.java b/testcontainers-advanced-imagebuilder/src/test/java/software/xdev/testcontainers/imagebuilder/compat/DockerfileCOPYParentsEmulatorTest.java index 03b1235..4e79f7f 100644 --- a/testcontainers-advanced-imagebuilder/src/test/java/software/xdev/testcontainers/imagebuilder/compat/DockerfileCOPYParentsEmulatorTest.java +++ b/testcontainers-advanced-imagebuilder/src/test/java/software/xdev/testcontainers/imagebuilder/compat/DockerfileCOPYParentsEmulatorTest.java @@ -33,29 +33,39 @@ void simpleCheck() "FROM alpine:3", "COPY --parents mvnw .mvn/** --abc ./", "COPY --parents **/pom.xml ./", - "COPY --parents abc/def.txt ./" + "COPY --parents abc/def.txt ./", + "COPY --parents ./d/e/** ./", + "COPY ./d/e/** ./", // Keep original + "COPY --parents ./it/mvnw ./it/.mvn/** ./xx" ), Set.of( - ".mvn/wrapper/maven-wrapper.properties", "mvnw", + ".mvn/wrapper/maven-wrapper.properties", "Dockerfile", "pom.xml", "a/pom.xml", "a/b/pom.xml", "a/b/c/pom.xml", "abc/def.txt", - "ignoreme.txt" + "ignoreme.txt", + "d/e/example.txt", + "it/mvnw", + "it/.mvn/wrapper/maven-wrapper.properties" )); Assertions.assertIterableEquals( List.of( "# syntax=docker/dockerfile:1-labs", "FROM alpine:3", - "COPY mvnw --abc ./", + "COPY mvnw --abc ./mvnw", "COPY .mvn/wrapper/maven-wrapper.properties --abc ./.mvn/wrapper/maven-wrapper.properties", "COPY a/b/c/pom.xml ./a/b/c/pom.xml", "COPY a/b/pom.xml ./a/b/pom.xml", "COPY a/pom.xml ./a/pom.xml", "COPY pom.xml ./pom.xml", - "COPY abc/def.txt ./abc/def.txt" + "COPY abc/def.txt ./abc/def.txt", + "COPY d/e/example.txt ./d/e/example.txt", + "COPY ./d/e/** ./", // Keep original + "COPY ./it/mvnw ./xx/it/mvnw", + "COPY it/.mvn/wrapper/maven-wrapper.properties ./xx/it/.mvn/wrapper/maven-wrapper.properties" ), lines); }