fix(cmd/podman/quadlet): Behave like container ls

Quadlet list always reports the heading, even when using custom
formatting strings. This doesn't follow the behavior of other podman
list commands. Borrow some logic and the "--noheading" flag from the
container list command to make this behavior uniform.

Signed-off-by: Randolph Sapp <rs@ti.com>
This commit is contained in:
Randolph Sapp
2026-02-27 23:54:14 -06:00
parent d3a81e3e17
commit 33a36bd56b
5 changed files with 62 additions and 13 deletions

View File

@@ -42,6 +42,8 @@ func listFlags(cmd *cobra.Command) {
flags.StringVar(&format, formatFlagName, "{{range .}}{{.Name}}\t{{.UnitName}}\t{{.Path}}\t{{.Status}}\t{{.App}}\n{{end -}}", "Pretty-print output to JSON or using a Go template")
_ = quadletListCmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(&entities.ListQuadlet{}))
_ = quadletListCmd.RegisterFlagCompletionFunc(filterFlagName, common.AutocompleteQuadletFilters)
flags.BoolP("noheading", "n", false, "Do not print headers")
}
func init() {
@@ -65,13 +67,10 @@ func list(cmd *cobra.Command, _ []string) error {
}
func outputTemplate(cmd *cobra.Command, responses []*entities.ListQuadlet) error {
headers := report.Headers(entities.ListQuadlet{}, map[string]string{
"Name": "NAME",
"UnitName": "UNIT NAME",
"Path": "PATH ON DISK",
"Status": "STATUS",
"App": "APPLICATION",
})
renderHeaders := true
if noHeading, _ := cmd.Flags().GetBool("noheading"); noHeading {
renderHeaders = false
}
rpt := report.New(os.Stdout, cmd.Name())
defer rpt.Flush()
@@ -86,8 +85,18 @@ func outputTemplate(cmd *cobra.Command, responses []*entities.ListQuadlet) error
return err
}
if err := rpt.Execute(headers); err != nil {
return fmt.Errorf("writing column headers: %w", err)
if renderHeaders && rpt.RenderHeaders {
headers := report.Headers(entities.ListQuadlet{}, map[string]string{
"Name": "NAME",
"UnitName": "UNIT NAME",
"Path": "PATH ON DISK",
"Status": "STATUS",
"App": "APPLICATION",
})
if err := rpt.Execute(headers); err != nil {
return fmt.Errorf("writing column headers: %w", err)
}
}
return rpt.Execute(responses)

View File

@@ -54,6 +54,7 @@ podman-port.1.md
podman-ps.1.md
podman-pull.1.md
podman-push.1.md
podman-quadlet-list.1.md
podman-restart.1.md
podman-rm.1.md
podman-run.1.md

View File

@@ -1,5 +1,5 @@
####> This option file is used in:
####> podman artifact ls, image trust, images, machine list, network ls, pod ps, secret ls, volume ls
####> podman artifact ls, image trust, images, machine list, network ls, pod ps, quadlet list, secret ls, volume ls
####> If file is edited, make sure the changes
####> are applicable to all of those.
#### **--noheading**, **-n**

View File

@@ -38,6 +38,8 @@ Print results with a Go template.
| .Status | Quadlet status corresponding to systemd unit |
| .UnitName | Systemd unit name corresponding to quadlet |
@@option noheading
## EXAMPLES
Simple list command
@@ -61,7 +63,6 @@ test-service-quadlet.container test-service-quadlet.service /home/user/.config
Format list output for a specific field.
```
$ podman quadlet list --format '{{ .UnitName }}'
UNIT NAME
test-service-quadlet.service
sample-quadlet.service
```

View File

@@ -371,7 +371,7 @@ EOF
# Test custom Go template format - extract only names
run_podman quadlet list --format '{{range .}}{{.Name}}{{"\n"}}{{end}}'
assert $status -eq 0 "quadlet list with custom format should succeed"
assert "$output" = $'NAME\nformat-test.container' "custom format should show only the name"
assert "$output" = $'format-test.container' "custom format should show only the name"
# Test custom Go template format - extract multiple fields
run_podman quadlet list --format '{{range .}}Name:{{.Name}} Status:{{.Status}}{{"\n"}}{{end}}'
@@ -382,12 +382,50 @@ EOF
# Test format with specific field extraction
run_podman quadlet list --format '{{.Name}}'
assert $status -eq 0 "quadlet list with field format should succeed"
assert "$output" = $'NAME\nformat-test.container' "field format should extract just the name"
assert "$output" = $'format-test.container' "field format should extract just the name"
# Clean up
run_podman quadlet rm format-test.container
}
@test "quadlet verb - list with --noheading option" {
run_podman quadlet list
assert $status -eq 0 "baseline: quadlet list should succeed"
assert "$output" =~ "^NAME" "baseline: default format should start with a heading"
assert "${#lines[@]}" -eq 1 "baseline: list with no quadlets should contain exactly one line"
run_podman quadlet list --noheading
assert $status -eq 0 "baseline: quadlet list --noheading should succeed"
assert "$output" == "" "baseline: empty results from quadlet list --noheading"
# Create a test quadlet file
local quadlet_file=$PODMAN_TMPDIR/noheading-test.container
cat > $quadlet_file <<EOF
[Container]
Image=$IMAGE
Exec=sh -c "echo STARTED CONTAINER FOR FORMAT TEST; trap 'exit' SIGTERM; while :; do sleep 0.1; done"
EOF
# Install the quadlet
run_podman quadlet install "$quadlet_file"
# Test default format (should show tabular output)
run_podman quadlet list
assert $status -eq 0 "quadlet list should succeed"
assert "$output" =~ "^NAME" "default format should start with a heading"
assert "$output" =~ "noheading-test.container" "default format should contain quadlet name"
assert "${#lines[@]}" -eq 2 "list output should contain exactly two lines"
# Test output without heading
run_podman quadlet list --noheading
assert $status -eq 0 "quadlet list --noheading should succeed"
assert "$output" =~ "^noheading-test.container" "noheading should should contain only the quadlet name"
assert "${#lines[@]}" -eq 1 "list output should contain exactly one line"
# Clean up
run_podman quadlet rm noheading-test.container
}
@test "quadlet verb - rm --all and --ignore options" {
# Create multiple test quadlet files
local quadlet_file1=$PODMAN_TMPDIR/rm-all-test1.container