diff --git a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/type/ImageName.java b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/type/ImageName.java
index f11439d992..889fee1263 100644
--- a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/type/ImageName.java
+++ b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/type/ImageName.java
@@ -16,6 +16,9 @@
package org.springframework.boot.buildpack.platform.docker.type;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
import org.springframework.util.Assert;
/**
@@ -25,11 +28,12 @@ import org.springframework.util.Assert;
* @author Scott Frederick
* @since 2.3.0
* @see ImageReference
- * @see ImageReferenceParser
* @see #of(String)
*/
public class ImageName {
+ private static final Pattern PATTERN = Regex.IMAGE_NAME.compile();
+
private static final String DEFAULT_DOMAIN = "docker.io";
private static final String OFFICIAL_REPOSITORY_NAME = "library";
@@ -42,10 +46,10 @@ public class ImageName {
private final String string;
- ImageName(String domain, String name) {
- Assert.hasText(name, "Name must not be empty");
+ ImageName(String domain, String path) {
+ Assert.hasText(path, "Path must not be empty");
this.domain = getDomainOrDefault(domain);
- this.name = getNameWithDefaultPath(this.domain, name);
+ this.name = getNameWithDefaultPath(this.domain, path);
this.string = this.domain + "/" + this.name;
}
@@ -128,8 +132,12 @@ public class ImageName {
*/
public static ImageName of(String value) {
Assert.hasText(value, "Value must not be empty");
- ImageReferenceParser parser = ImageReferenceParser.of(value);
- return new ImageName(parser.getDomain(), parser.getName());
+ Matcher matcher = PATTERN.matcher(value);
+ Assert.isTrue(matcher.matches(),
+ () -> "Unable to parse name \"" + value + "\". "
+ + "Image name must be in the form '[domainHost:port/][path/]name', "
+ + "with 'path' and 'name' containing only [a-z0-9][.][_][-]");
+ return new ImageName(matcher.group("domain"), matcher.group("path"));
}
}
diff --git a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/type/ImageReference.java b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/type/ImageReference.java
index 093b510b13..4393cc6fe5 100644
--- a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/type/ImageReference.java
+++ b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/type/ImageReference.java
@@ -30,13 +30,14 @@ import org.springframework.util.ObjectUtils;
* @author Scott Frederick
* @since 2.3.0
* @see ImageName
- * @see ImageReferenceParser
*/
public final class ImageReference {
- private static final String LATEST = "latest";
+ private static final Pattern PATTERN = Regex.IMAGE_REFERENCE.compile();
+
+ private static final Pattern JAR_VERSION_PATTERN = Pattern.compile("^(.*)(\\-\\d+)$");
- private static final Pattern TRAILING_VERSION_PATTERN = Pattern.compile("^(.*)(\\-\\d+)$");
+ private static final String LATEST = "latest";
private final ImageName name;
@@ -182,7 +183,7 @@ public final class ImageReference {
}
String name = filename.substring(0, firstDot);
String version = filename.substring(firstDot + 1);
- Matcher matcher = TRAILING_VERSION_PATTERN.matcher(name);
+ Matcher matcher = JAR_VERSION_PATTERN.matcher(name);
if (matcher.matches()) {
name = matcher.group(1);
version = matcher.group(2).substring(1) + "." + version;
@@ -224,9 +225,13 @@ public final class ImageReference {
*/
public static ImageReference of(String value) {
Assert.hasText(value, "Value must not be null");
- ImageReferenceParser parser = ImageReferenceParser.of(value);
- ImageName name = new ImageName(parser.getDomain(), parser.getName());
- return new ImageReference(name, parser.getTag(), parser.getDigest());
+ Matcher matcher = PATTERN.matcher(value);
+ Assert.isTrue(matcher.matches(),
+ () -> "Unable to parse image reference \"" + value + "\". "
+ + "Image reference must be in the form '[domainHost:port/][path/]name[:tag][@digest]', "
+ + "with 'path' and 'name' containing only [a-z0-9][.][_][-]");
+ ImageName name = new ImageName(matcher.group("domain"), matcher.group("path"));
+ return new ImageReference(name, matcher.group("tag"), matcher.group("digest"));
}
/**
diff --git a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/type/ImageReferenceParser.java b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/type/ImageReferenceParser.java
deleted file mode 100644
index b20cc1dc2d..0000000000
--- a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/type/ImageReferenceParser.java
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Copyright 2012-2020 the original author or authors.
- *
- * 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
- *
- * https://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 org.springframework.boot.buildpack.platform.docker.type;
-
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * A parser for Docker image references in the form
- * {@code [domainHost:port/][path/]name[:tag][@digest]}.
- *
- * @author Scott Frederick
- * @see Docker
- * grammar reference
- * @see Docker grammar
- * implementation
- * @see How
- * are Docker image names parsed?
- */
-final class ImageReferenceParser {
-
- private static final String DOMAIN_SEGMENT_REGEX = "(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])";
-
- private static final String DOMAIN_PORT_REGEX = "[0-9]+";
-
- private static final String DOMAIN_REGEX = oneOf(
- groupOf(DOMAIN_SEGMENT_REGEX, repeating("[.]", DOMAIN_SEGMENT_REGEX)),
- groupOf(DOMAIN_SEGMENT_REGEX, "[:]", DOMAIN_PORT_REGEX),
- groupOf(DOMAIN_SEGMENT_REGEX, repeating("[.]", DOMAIN_SEGMENT_REGEX), "[:]", DOMAIN_PORT_REGEX),
- "localhost");
-
- private static final String NAME_CHARS_REGEX = "[a-z0-9]+";
-
- private static final String NAME_SEPARATOR_REGEX = "(?:[._]|__|[-]*)";
-
- private static final String NAME_SEGMENT_REGEX = groupOf(NAME_CHARS_REGEX,
- optional(repeating(NAME_SEPARATOR_REGEX, NAME_CHARS_REGEX)));
-
- private static final String NAME_PATH_REGEX = groupOf(NAME_SEGMENT_REGEX,
- optional(repeating("[/]", NAME_SEGMENT_REGEX)));
-
- private static final String DIGEST_ALGORITHM_SEGMENT_REGEX = "[A-Za-z][A-Za-z0-9]*";
-
- private static final String DIGEST_ALGORITHM_SEPARATOR_REGEX = "[-_+.]";
-
- private static final String DIGEST_ALGORITHM_REGEX = groupOf(DIGEST_ALGORITHM_SEGMENT_REGEX,
- optional(repeating(DIGEST_ALGORITHM_SEPARATOR_REGEX, DIGEST_ALGORITHM_SEGMENT_REGEX)));
-
- private static final String DIGEST_VALUE_REGEX = "[0-9A-Fa-f]{32,}";
-
- private static final String DIGEST_REGEX = groupOf(DIGEST_ALGORITHM_REGEX, "[:]", DIGEST_VALUE_REGEX);
-
- private static final String TAG_REGEX = "[\\w][\\w.-]{0,127}";
-
- private static final String DOMAIN_CAPTURE_GROUP = "domain";
-
- private static final String NAME_CAPTURE_GROUP = "name";
-
- private static final String TAG_CAPTURE_GROUP = "tag";
-
- private static final String DIGEST_CAPTURE_GROUP = "digest";
-
- private static final Pattern REFERENCE_REGEX_PATTERN = patternOf(anchored(
- optional(captureOf(DOMAIN_CAPTURE_GROUP, DOMAIN_REGEX), "[/]"),
- captureOf(NAME_CAPTURE_GROUP, NAME_PATH_REGEX), optional("[:]", captureOf(TAG_CAPTURE_GROUP, TAG_REGEX)),
- optional("[@]", captureOf(DIGEST_CAPTURE_GROUP, DIGEST_REGEX))));
-
- private final String domain;
-
- private final String name;
-
- private final String tag;
-
- private final String digest;
-
- private ImageReferenceParser(String domain, String name, String tag, String digest) {
- this.domain = domain;
- this.name = name;
- this.tag = tag;
- this.digest = digest;
- }
-
- String getDomain() {
- return this.domain;
- }
-
- String getName() {
- return this.name;
- }
-
- String getTag() {
- return this.tag;
- }
-
- String getDigest() {
- return this.digest;
- }
-
- static ImageReferenceParser of(String reference) {
- Matcher matcher = REFERENCE_REGEX_PATTERN.matcher(reference);
- if (!matcher.matches()) {
- throw new IllegalArgumentException("Unable to parse image reference \"" + reference + "\". "
- + "Image reference must be in the form \"[domainHost:port/][path/]name[:tag][@digest]\", "
- + "with \"path\" and \"name\" containing only [a-z0-9][.][_][-]");
- }
- return new ImageReferenceParser(matcher.group(DOMAIN_CAPTURE_GROUP), matcher.group(NAME_CAPTURE_GROUP),
- matcher.group(TAG_CAPTURE_GROUP), matcher.group(DIGEST_CAPTURE_GROUP));
- }
-
- private static Pattern patternOf(String... expressions) {
- return Pattern.compile(join(expressions));
- }
-
- private static String groupOf(String... expressions) {
- return "(?:" + join(expressions) + ')';
- }
-
- private static String captureOf(String groupName, String... expressions) {
- return "(?<" + groupName + ">" + join(expressions) + ')';
- }
-
- private static String oneOf(String... expressions) {
- return groupOf(String.join("|", expressions));
- }
-
- private static String optional(String... expressions) {
- return groupOf(join(expressions)) + '?';
- }
-
- private static String repeating(String... expressions) {
- return groupOf(join(expressions)) + '+';
- }
-
- private static String anchored(String... expressions) {
- return '^' + join(expressions) + '$';
- }
-
- private static String join(String... expressions) {
- return String.join("", expressions);
- }
-
-}
diff --git a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/type/Regex.java b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/type/Regex.java
new file mode 100644
index 0000000000..2307ccc4e5
--- /dev/null
+++ b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/type/Regex.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright 2012-2020 the original author or authors.
+ *
+ * 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
+ *
+ * https://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 org.springframework.boot.buildpack.platform.docker.type;
+
+import java.util.regex.Pattern;
+
+/**
+ * Regular Expressions for image names and references based on those found in the Docker
+ * codebase.
+ *
+ * @author Scott Frederick
+ * @author Phillip Webb
+ * @see Docker
+ * grammar reference
+ * @see Docker grammar
+ * implementation
+ * @see How
+ * are Docker image names parsed?
+ */
+final class Regex implements CharSequence {
+
+ private static final Regex DOMAIN;
+ static {
+ Regex component = Regex.oneOf("[a-zA-Z0-9]", "[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]");
+ Regex dotComponent = Regex.group("[.]", component);
+ Regex colonPort = Regex.of("[:][0-9]+");
+ Regex dottedDomain = Regex.group(component, dotComponent.oneOrMoreTimes());
+ Regex dottedDomainAndPort = Regex.group(component, dotComponent.oneOrMoreTimes(), colonPort);
+ Regex nameAndPort = Regex.group(component, colonPort);
+ DOMAIN = Regex.oneOf(dottedDomain, nameAndPort, dottedDomainAndPort, "localhost");
+ }
+
+ private static final Regex PATH_COMPONENT;
+ static {
+ Regex segment = Regex.of("[a-z0-9]+");
+ Regex separator = Regex.group("[._]|__|[-]*");
+ Regex separatedSegment = Regex.group(separator, segment).oneOrMoreTimes();
+ PATH_COMPONENT = Regex.of(segment, Regex.group(separatedSegment).zeroOrOnce());
+ }
+
+ private static final Regex PATH;
+ static {
+ Regex component = PATH_COMPONENT;
+ Regex slashComponent = Regex.group("[/]", component);
+ Regex slashComponents = Regex.group(slashComponent.oneOrMoreTimes());
+ PATH = Regex.of(component, slashComponents.zeroOrOnce());
+ }
+
+ static final Regex IMAGE_NAME;
+ static {
+ Regex domain = DOMAIN.capturedAs("domain");
+ Regex domainSlash = Regex.group(domain, "[/]");
+ Regex path = PATH.capturedAs("path");
+ Regex optionalDomainSlash = domainSlash.zeroOrOnce();
+ IMAGE_NAME = Regex.of(optionalDomainSlash, path);
+ }
+
+ private static final Regex TAG_REGEX = Regex.of("[\\w][\\w.-]{0,127}");
+
+ private static final Regex DIGEST_REGEX = Regex
+ .of("[A-Za-z][A-Za-z0-9]*(?:[-_+.][A-Za-z][A-Za-z0-9]*)*[:][[A-Fa-f0-9]]{32,}");
+
+ static final Regex IMAGE_REFERENCE;
+ static {
+ Regex tag = TAG_REGEX.capturedAs("tag");
+ Regex digest = DIGEST_REGEX.capturedAs("digest");
+ Regex atDigest = Regex.group("[@]", digest);
+ Regex colonTag = Regex.group("[:]", tag);
+ IMAGE_REFERENCE = Regex.of(IMAGE_NAME, colonTag.zeroOrOnce(), atDigest.zeroOrOnce());
+ }
+
+ private final String value;
+
+ private Regex(CharSequence value) {
+ this.value = value.toString();
+ }
+
+ private Regex oneOrMoreTimes() {
+ return new Regex(this.value + "+");
+ }
+
+ private Regex zeroOrOnce() {
+ return new Regex(this.value + "?");
+ }
+
+ private Regex capturedAs(String name) {
+ return new Regex("(?<" + name + ">" + this + ")");
+ }
+
+ Pattern compile() {
+ return Pattern.compile("^" + this.value + "$");
+ }
+
+ @Override
+ public int length() {
+ return this.value.length();
+ }
+
+ @Override
+ public char charAt(int index) {
+ return this.value.charAt(index);
+ }
+
+ @Override
+ public CharSequence subSequence(int start, int end) {
+ return this.value.subSequence(start, end);
+ }
+
+ @Override
+ public String toString() {
+ return this.value;
+ }
+
+ private static Regex of(CharSequence... expressions) {
+ return new Regex(String.join("", expressions));
+ }
+
+ private static Regex oneOf(CharSequence... expressions) {
+ return new Regex("(?:" + String.join("|", expressions) + ")");
+ }
+
+ private static Regex group(CharSequence... expressions) {
+ return new Regex("(?:" + String.join("", expressions) + ")");
+ }
+
+}
diff --git a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/docker/type/ImageNameTests.java b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/docker/type/ImageNameTests.java
index f994e40047..c1e667e093 100644
--- a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/docker/type/ImageNameTests.java
+++ b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/docker/type/ImageNameTests.java
@@ -71,12 +71,42 @@ class ImageNameTests {
@Test
void ofWhenSimpleNameAndPortCreatesImageName() {
+ ImageName imageName = ImageName.of("repo:8080/ubuntu");
+ assertThat(imageName.toString()).isEqualTo("repo:8080/ubuntu");
+ assertThat(imageName.getDomain()).isEqualTo("repo:8080");
+ assertThat(imageName.getName()).isEqualTo("ubuntu");
+ }
+
+ @Test
+ void ofWhenSimplePathAndPortCreatesImageName() {
ImageName imageName = ImageName.of("repo:8080/canonical/ubuntu");
assertThat(imageName.toString()).isEqualTo("repo:8080/canonical/ubuntu");
assertThat(imageName.getDomain()).isEqualTo("repo:8080");
assertThat(imageName.getName()).isEqualTo("canonical/ubuntu");
}
+ @Test
+ void ofWhenNameWithLongPathCreatesImageName() {
+ ImageName imageName = ImageName.of("path1/path2/path3/ubuntu");
+ assertThat(imageName.toString()).isEqualTo("docker.io/path1/path2/path3/ubuntu");
+ assertThat(imageName.getDomain()).isEqualTo("docker.io");
+ assertThat(imageName.getName()).isEqualTo("path1/path2/path3/ubuntu");
+ }
+
+ @Test
+ void ofWhenLocalhostDomainCreatesImageName() {
+ ImageName imageName = ImageName.of("localhost/ubuntu");
+ assertThat(imageName.getDomain()).isEqualTo("localhost");
+ assertThat(imageName.getName()).isEqualTo("ubuntu");
+ }
+
+ @Test
+ void ofWhenLocalhostDomainAndPathCreatesImageName() {
+ ImageName imageName = ImageName.of("localhost/library/ubuntu");
+ assertThat(imageName.getDomain()).isEqualTo("localhost");
+ assertThat(imageName.getName()).isEqualTo("library/ubuntu");
+ }
+
@Test
void ofWhenLegacyDomainUsesNewDomain() {
ImageName imageName = ImageName.of("index.docker.io/ubuntu");
@@ -96,6 +126,25 @@ class ImageNameTests {
assertThatIllegalArgumentException().isThrownBy(() -> ImageName.of("")).withMessage("Value must not be empty");
}
+ @Test
+ void ofWhenContainsUppercaseThrowsException() {
+ assertThatIllegalArgumentException().isThrownBy(() -> ImageName.of("Test"))
+ .withMessageContaining("Unable to parse name").withMessageContaining("Test");
+ }
+
+ @Test
+ void ofWhenNameIncludesTagThrowsException() {
+ assertThatIllegalArgumentException().isThrownBy(() -> ImageName.of("ubuntu:latest"))
+ .withMessageContaining("Unable to parse name").withMessageContaining(":latest");
+ }
+
+ @Test
+ void ofWhenNameIncludeDigestThrowsException() {
+ assertThatIllegalArgumentException().isThrownBy(
+ () -> ImageName.of("ubuntu@sha256:47bfdb88c3ae13e488167607973b7688f69d9e8c142c2045af343ec199649c09"))
+ .withMessageContaining("Unable to parse name").withMessageContaining("@sha256:47b");
+ }
+
@Test
void hashCodeAndEquals() {
ImageName n1 = ImageName.of("ubuntu");
diff --git a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/docker/type/ImageReferenceParserTests.java b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/docker/type/ImageReferenceParserTests.java
deleted file mode 100644
index f7abe4898d..0000000000
--- a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/docker/type/ImageReferenceParserTests.java
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * Copyright 2012-2020 the original author or authors.
- *
- * 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
- *
- * https://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 org.springframework.boot.buildpack.platform.docker.type;
-
-import org.junit.jupiter.api.Test;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
-
-/**
- * Tests for {@link ImageReferenceParser}.
- *
- * @author Scott Frederick
- */
-class ImageReferenceParserTests {
-
- @Test
- void unableToParseWithUppercaseInName() {
- assertThatIllegalArgumentException().isThrownBy(() -> ImageReferenceParser.of("Test"))
- .withMessageContaining("Test");
- }
-
- @Test
- void parsesName() {
- ImageReferenceParser parser = ImageReferenceParser.of("ubuntu");
- assertThat(parser.getDomain()).isNull();
- assertThat(parser.getName()).isEqualTo("ubuntu");
- assertThat(parser.getTag()).isNull();
- assertThat(parser.getDigest()).isNull();
- }
-
- @Test
- void parsesNameWithPath() {
- ImageReferenceParser parser = ImageReferenceParser.of("library/ubuntu");
- assertThat(parser.getDomain()).isNull();
- assertThat(parser.getName()).isEqualTo("library/ubuntu");
- assertThat(parser.getTag()).isNull();
- assertThat(parser.getDigest()).isNull();
- }
-
- @Test
- void parsesNameWithLongPath() {
- ImageReferenceParser parser = ImageReferenceParser.of("path1/path2/path3/ubuntu");
- assertThat(parser.getDomain()).isNull();
- assertThat(parser.getName()).isEqualTo("path1/path2/path3/ubuntu");
- assertThat(parser.getTag()).isNull();
- assertThat(parser.getDigest()).isNull();
- }
-
- @Test
- void parsesDomainAndNameWithPath() {
- ImageReferenceParser parser = ImageReferenceParser.of("repo.example.com/library/ubuntu");
- assertThat(parser.getDomain()).isEqualTo("repo.example.com");
- assertThat(parser.getName()).isEqualTo("library/ubuntu");
- assertThat(parser.getTag()).isNull();
- assertThat(parser.getDigest()).isNull();
- }
-
- @Test
- void parsesDomainWithPortAndNameWithPath() {
- ImageReferenceParser parser = ImageReferenceParser.of("repo.example.com:8080/library/ubuntu");
- assertThat(parser.getDomain()).isEqualTo("repo.example.com:8080");
- assertThat(parser.getName()).isEqualTo("library/ubuntu");
- assertThat(parser.getTag()).isNull();
- assertThat(parser.getDigest()).isNull();
- }
-
- @Test
- void parsesSimpleDomainWithPortAndName() {
- ImageReferenceParser parser = ImageReferenceParser.of("repo:8080/ubuntu");
- assertThat(parser.getDomain()).isEqualTo("repo:8080");
- assertThat(parser.getName()).isEqualTo("ubuntu");
- assertThat(parser.getTag()).isNull();
- assertThat(parser.getDigest()).isNull();
- }
-
- @Test
- void parsesSimpleDomainWithPortAndNameWithPath() {
- ImageReferenceParser parser = ImageReferenceParser.of("repo:8080/library/ubuntu");
- assertThat(parser.getDomain()).isEqualTo("repo:8080");
- assertThat(parser.getName()).isEqualTo("library/ubuntu");
- assertThat(parser.getTag()).isNull();
- assertThat(parser.getDigest()).isNull();
- }
-
- @Test
- void parsesLocalhostDomainAndName() {
- ImageReferenceParser parser = ImageReferenceParser.of("localhost/ubuntu");
- assertThat(parser.getDomain()).isEqualTo("localhost");
- assertThat(parser.getName()).isEqualTo("ubuntu");
- assertThat(parser.getTag()).isNull();
- assertThat(parser.getDigest()).isNull();
- }
-
- @Test
- void parsesLocalhostDomainAndNameWithPath() {
- ImageReferenceParser parser = ImageReferenceParser.of("localhost/library/ubuntu");
- assertThat(parser.getDomain()).isEqualTo("localhost");
- assertThat(parser.getName()).isEqualTo("library/ubuntu");
- assertThat(parser.getTag()).isNull();
- assertThat(parser.getDigest()).isNull();
- }
-
- @Test
- void parsesNameAndTag() {
- ImageReferenceParser parser = ImageReferenceParser.of("ubuntu:v1");
- assertThat(parser.getDomain()).isNull();
- assertThat(parser.getName()).isEqualTo("ubuntu");
- assertThat(parser.getTag()).isEqualTo("v1");
- assertThat(parser.getDigest()).isNull();
- }
-
- @Test
- void parsesNameAndDigest() {
- ImageReferenceParser parser = ImageReferenceParser
- .of("ubuntu@sha256:47bfdb88c3ae13e488167607973b7688f69d9e8c142c2045af343ec199649c09");
- assertThat(parser.getDomain()).isNull();
- assertThat(parser.getName()).isEqualTo("ubuntu");
- assertThat(parser.getTag()).isNull();
- assertThat(parser.getDigest())
- .isEqualTo("sha256:47bfdb88c3ae13e488167607973b7688f69d9e8c142c2045af343ec199649c09");
- }
-
- @Test
- void parsesReferenceWithTag() {
- ImageReferenceParser parser = ImageReferenceParser.of("repo.example.com:8080/library/ubuntu:v1");
- assertThat(parser.getDomain()).isEqualTo("repo.example.com:8080");
- assertThat(parser.getName()).isEqualTo("library/ubuntu");
- assertThat(parser.getTag()).isEqualTo("v1");
- assertThat(parser.getDigest()).isNull();
- }
-
- @Test
- void parsesReferenceWithDigest() {
- ImageReferenceParser parser = ImageReferenceParser.of(
- "repo.example.com:8080/library/ubuntu@sha256:47bfdb88c3ae13e488167607973b7688f69d9e8c142c2045af343ec199649c09");
- assertThat(parser.getDomain()).isEqualTo("repo.example.com:8080");
- assertThat(parser.getName()).isEqualTo("library/ubuntu");
- assertThat(parser.getTag()).isNull();
- assertThat(parser.getDigest())
- .isEqualTo("sha256:47bfdb88c3ae13e488167607973b7688f69d9e8c142c2045af343ec199649c09");
- }
-
-}
diff --git a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/docker/type/ImageReferenceTests.java b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/docker/type/ImageReferenceTests.java
index 5b22402767..134db76f11 100644
--- a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/docker/type/ImageReferenceTests.java
+++ b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/docker/type/ImageReferenceTests.java
@@ -102,6 +102,16 @@ class ImageReferenceTests {
assertThat(reference.toString()).isEqualTo("docker.io/library/ubuntu:bionic");
}
+ @Test
+ void ofDomainPortAndTag() {
+ ImageReference reference = ImageReference.of("repo.example.com:8080/library/ubuntu:v1");
+ assertThat(reference.getDomain()).isEqualTo("repo.example.com:8080");
+ assertThat(reference.getName()).isEqualTo("library/ubuntu");
+ assertThat(reference.getTag()).isEqualTo("v1");
+ assertThat(reference.getDigest()).isNull();
+ assertThat(reference.toString()).isEqualTo("repo.example.com:8080/library/ubuntu:v1");
+ }
+
@Test
void ofNameAndDigest() {
ImageReference reference = ImageReference