Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions Sources/ContainerResource/Image/ImageResource.swift
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,14 @@ public struct ImageResource: ManagedResource {

// MARK: ManagedResource

/// The unique identifier for this image. Identical to the image's index digest.
public var id: String { configuration.descriptor.digest }
/// The scheme-specific value of `configuration.descriptor.digest` (the hex portion
/// after the algorithm prefix). The fully-qualified digest — needed for content-store
/// lookups and XPC transport — is always recoverable as `configuration.descriptor.digest`.
public var id: String {
let digest = configuration.descriptor.digest
guard let colonIndex = digest.firstIndex(of: ":") else { return digest }
return String(digest[digest.index(after: colonIndex)...])
}

/// The user-facing reference (`name:tag`) for this image.
public var name: String { configuration.name }
Expand Down
9 changes: 4 additions & 5 deletions Sources/Services/ContainerAPIService/Client/Utility.swift
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,11 @@ public struct Utility {
}

public static func trimDigest(digest: String) -> String {
var digest = digest
digest.trimPrefix("sha256:")
if digest.count > 24 {
digest = String(digest.prefix(24)) + "..."
var hex = digest
if let colonIndex = digest.firstIndex(of: ":") {
hex = String(digest[digest.index(after: colonIndex)...])
}
return digest
return String(hex.prefix(12))
}

public static func validEntityName(_ name: String) throws {
Expand Down
23 changes: 23 additions & 0 deletions Tests/ContainerAPIClientTests/UtilityTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,29 @@ struct UtilityTests {
}
}

@Test("Trim fully-qualified digest strips scheme and truncates to 12 chars")
func testTrimDigestFullyQualified() {
let hex = "0be69a25c33692845efb1e93f4254f28505a330896376bf8"
#expect(Utility.trimDigest(digest: "sha256:\(hex)") == String(hex.prefix(12)))
}

@Test("Trim digest with unknown scheme strips scheme prefix")
func testTrimDigestUnknownScheme() {
let hex = "abcdef123456789012345678"
#expect(Utility.trimDigest(digest: "blake3:\(hex)") == String(hex.prefix(12)))
}

@Test("Trim digest with no scheme truncates directly")
func testTrimDigestNoScheme() {
let hex = "abcdef1234567890"
#expect(Utility.trimDigest(digest: hex) == String(hex.prefix(12)))
}

@Test("Trim digest shorter than 12 chars returns value unchanged")
func testTrimDigestShort() {
#expect(Utility.trimDigest(digest: "sha256:abc") == "abc")
}

@Test
func testPublishPortParser() throws {
let ports = try Parser.publishPorts([
Expand Down
4 changes: 2 additions & 2 deletions docs/tutorials/start-here.md
Original file line number Diff line number Diff line change
Expand Up @@ -163,8 +163,8 @@ After the build completes, list the images. You should see both the base image a
<pre>
% container image list
NAME TAG DIGEST
python alpine b4d299311845147e7e47c970...
web-test latest 25b99501f174803e21c58f9c...
python alpine b4d299311845
web-test latest 25b99501f174
%
</pre>

Expand Down