diff --git a/src/main/generated/Versions.java b/src/main/generated/Versions.java index 3860dba..73f795a 100644 --- a/src/main/generated/Versions.java +++ b/src/main/generated/Versions.java @@ -30,6 +30,11 @@ */ @NullMarked public final class Versions { + + private Versions() { + // Prevent instantiation + } + /** * User agent value */ diff --git a/src/main/java/land/oras/LayoutRef.java b/src/main/java/land/oras/LayoutRef.java index a3beca9..4bafc75 100644 --- a/src/main/java/land/oras/LayoutRef.java +++ b/src/main/java/land/oras/LayoutRef.java @@ -25,6 +25,7 @@ import land.oras.exception.OrasException; import land.oras.utils.SupportedAlgorithm; import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; /** * A referer of a container on a {@link OCILayout}. @@ -43,7 +44,7 @@ public final class LayoutRef extends Ref { * Private constructor * @param tag The tag. */ - private LayoutRef(Path folder, String tag) { + private LayoutRef(Path folder, @Nullable String tag) { super(tag); this.folder = folder; } @@ -85,6 +86,25 @@ public static LayoutRef parse(String name) { return new LayoutRef(path, tag); } + /** + * Return a new layout reference for a path and digest or tag + * @param layout The OCI layout + * @param digest The digest + * @return The layout ref + */ + public static LayoutRef of(OCILayout layout, String digest) { + return new LayoutRef(layout.getPath(), digest); + } + + /** + * Return a new layout reference for a path and digest or tag + * @param layout The OCI layout + * @return The layout ref + */ + public static LayoutRef of(OCILayout layout) { + return new LayoutRef(layout.getPath(), null); + } + /** * Return a new layout reference for a path * @param path The path diff --git a/src/main/java/land/oras/Ref.java b/src/main/java/land/oras/Ref.java index b1903c0..7eb557e 100644 --- a/src/main/java/land/oras/Ref.java +++ b/src/main/java/land/oras/Ref.java @@ -40,7 +40,7 @@ public abstract sealed class Ref> permits ContainerRef, LayoutR * Constructor * @param tag The tag */ - protected Ref(String tag) { + protected Ref(@Nullable String tag) { this.tag = tag; } diff --git a/src/test/java/land/oras/OCILayoutTest.java b/src/test/java/land/oras/OCILayoutTest.java index 6a02d25..8162e93 100644 --- a/src/test/java/land/oras/OCILayoutTest.java +++ b/src/test/java/land/oras/OCILayoutTest.java @@ -599,8 +599,8 @@ void shouldPushBlob() throws IOException { byte[] content = "hi".getBytes(StandardCharsets.UTF_8); String digest = SupportedAlgorithm.SHA256.digest(content); - LayoutRef layoutRef = LayoutRef.parse("%s@%s".formatted(path.toString(), digest)); OCILayout ociLayout = OCILayout.Builder.builder().defaults(path).build(); + LayoutRef layoutRef = LayoutRef.of(ociLayout, digest); // Push more blobs ociLayout.pushBlob(layoutRef, "hi".getBytes(StandardCharsets.UTF_8)); @@ -621,11 +621,12 @@ void cannotPushBlobWithoutTagOrDigest() throws IOException { Path invalidBlobPushDir = layoutPath.resolve("shouldPushArtifact"); - LayoutRef noTagLayout = LayoutRef.parse("%s".formatted(invalidBlobPushDir.toString())); - LayoutRef noDigestLayout = LayoutRef.parse("%s:latest".formatted(invalidBlobPushDir.toString())); OCILayout ociLayout = OCILayout.Builder.builder().defaults(invalidBlobPushDir).build(); + LayoutRef noTagLayout = LayoutRef.of(ociLayout); + LayoutRef noDigestLayout = LayoutRef.of(ociLayout, "latest"); + // Push more blobs assertThrows(OrasException.class, () -> { ociLayout.pushBlob(noTagLayout, "hi".getBytes(StandardCharsets.UTF_8)); @@ -665,7 +666,7 @@ void testShouldCopyArtifactFromRegistryIntoOciLayout() throws IOException { .build(); OCILayout ociLayout = OCILayout.builder().defaults(layoutPath).build(); - LayoutRef layoutRef = LayoutRef.parse("%s".formatted(ociLayout.getPath())); + LayoutRef layoutRef = LayoutRef.of(ociLayout); ContainerRef containerRef = ContainerRef.parse("%s/library/artifact-oci-layout".formatted(this.registry.getRegistry()));