Skip to content
Open
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
53 changes: 47 additions & 6 deletions cmd/podman/artifact/list.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package artifact

import (
"encoding/json"
"fmt"
"os"
"time"
Expand Down Expand Up @@ -41,6 +42,7 @@
Digest string
Repository string
Size string
sizeBytes int64
Tag string
created time.Time
VirtualSize string
Expand Down Expand Up @@ -84,13 +86,8 @@
return err
}

return outputTemplate(cmd, reports)
}

func outputTemplate(cmd *cobra.Command, lrs []*entities.ArtifactListReport) error {
var err error
artifacts := make([]artifactListOutput, 0)
for _, lr := range lrs {
for _, lr := range reports {
var tag string
artifactName, err := lr.Artifact.GetName()
if err != nil {
Expand Down Expand Up @@ -130,13 +127,57 @@
Digest: artifactHash,
Repository: named.Name(),
Size: units.HumanSize(float64(lr.Artifact.TotalSizeBytes())),
sizeBytes: lr.Artifact.TotalSizeBytes(),
Tag: tag,
created: createdTime,
VirtualSize: fmt.Sprintf("%d", lr.Artifact.TotalSizeBytes()),
virtualBytes: lr.Artifact.TotalSizeBytes(),
})
}

switch {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess a conditional if here and no conditional around the second part would kind of be the same ?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree. I matched the pattern in images/list.go as closely as I could (which also has a quiet option that only dumps the IDs, but maybe someone will want to add something like that here too).

case report.IsJSON(listFlag.format):
return writeJSON(artifacts)
default:
return writeTemplate(cmd, artifacts)
}

Check failure on line 144 in cmd/podman/artifact/list.go

View workflow job for this annotation

GitHub Actions / Validate source code changes

File is not properly formatted (gofumpt)
}

Check failure on line 145 in cmd/podman/artifact/list.go

View workflow job for this annotation

GitHub Actions / Validate source code changes

unnecessary trailing newline (whitespace)

func writeJSON(artifacts []artifactListOutput) error {
type artifact struct {
Repository string `json:"Repository,omitempty"`
CreatedAt string
Size int64
Tag string `json:"Tag,omitempty"`
Digest string
}

arti := make([]artifact, 0, len(artifacts))

for _, e := range artifacts {
var a artifact
a.Repository = e.Repository
a.CreatedAt = e.created.Format(time.RFC3339Nano)
a.Size = e.sizeBytes
a.Repository = e.Repository
a.Tag = e.Tag
a.Digest = e.Digest

arti = append(arti, a)
}

prettyJSON, err := json.MarshalIndent(arti, "", " ")
if err != nil {
return err
}
fmt.Println(string(prettyJSON))
return nil
}

func writeTemplate(cmd *cobra.Command, artifacts []artifactListOutput) error {
var err error

headers := report.Headers(artifactListOutput{}, map[string]string{
"REPOSITORY": "REPOSITORY",
"Tag": "TAG",
Expand Down
13 changes: 13 additions & 0 deletions docs/source/markdown/podman-artifact-ls.1.md.in
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,19 @@ ab609fad386d 2.097GB
cd734b558ceb 12.58MB
```

List artifact details in json format
```
$ podman artifact ls --format json"
[
{
"Repository": "quay.io/artifact/foobar1",
"CreatedAt": "2026-06-16T00:00:57Z",
"Size": 12580000,
"Tag": "special",
"Digest": "cd734b558ceb"
}
]
```


## SEE ALSO
Expand Down
18 changes: 18 additions & 0 deletions test/e2e/artifact_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
package integration

import (
"encoding/json"
"fmt"
"os"
"path/filepath"
Expand Down Expand Up @@ -51,6 +52,23 @@ var _ = Describe("Podman artifact", func() {
Expect(output).To(ContainElement(artifact1Name))
Expect(output).To(ContainElement(artifact2Name))

// --format=json should work, produce valid json
listFormatJsonSession := podmanTest.PodmanExitCleanly("artifact", "ls", "--format", "{{.Repository}}")
Expect(listFormatJsonSession).Should(ExitCleanly())
jsonOutput := listFormatJsonSession.OutputToString()
Expect(jsonOutput).To(BeValidJSON())

// --format=json should produce
jsonArtifactsList := []map[string]any{}
jsonUnmarshalErr := json.Unmarshal([]byte(jsonOutput), &jsonArtifactsList)

Expect(jsonUnmarshalErr).ToNot(HaveOccurred())
Expect(jsonArtifactsList).ToNot(BeEmpty())

for _, image := range jsonArtifactsList {
Expect(image).To(HaveKey("Repository"))
Expect(image).To(HaveKey("Tag"))
}
// Check default digest length (should be 12)
defaultFormatSession := podmanTest.PodmanExitCleanly("artifact", "ls", "--format", "{{.Digest}}")
defaultOutput := defaultFormatSession.OutputToStringArray()[0]
Expand Down
Loading