From 33a36bd56bbd5f9ea7490737c67a5e0363d333a7 Mon Sep 17 00:00:00 2001 From: Randolph Sapp Date: Fri, 27 Feb 2026 23:54:14 -0600 Subject: [PATCH] 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 --- cmd/podman/quadlet/list.go | 27 ++++++++---- docs/source/markdown/.gitignore | 1 + docs/source/markdown/options/noheading.md | 2 +- ...-list.1.md => podman-quadlet-list.1.md.in} | 3 +- test/system/253-podman-quadlet.bats | 42 ++++++++++++++++++- 5 files changed, 62 insertions(+), 13 deletions(-) rename docs/source/markdown/{podman-quadlet-list.1.md => podman-quadlet-list.1.md.in} (99%) diff --git a/cmd/podman/quadlet/list.go b/cmd/podman/quadlet/list.go index b4197a03c5..4b0db0ad6c 100644 --- a/cmd/podman/quadlet/list.go +++ b/cmd/podman/quadlet/list.go @@ -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) diff --git a/docs/source/markdown/.gitignore b/docs/source/markdown/.gitignore index 647b3ac344..aecb272761 100644 --- a/docs/source/markdown/.gitignore +++ b/docs/source/markdown/.gitignore @@ -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 diff --git a/docs/source/markdown/options/noheading.md b/docs/source/markdown/options/noheading.md index 623d21180a..6fd17d11aa 100644 --- a/docs/source/markdown/options/noheading.md +++ b/docs/source/markdown/options/noheading.md @@ -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** diff --git a/docs/source/markdown/podman-quadlet-list.1.md b/docs/source/markdown/podman-quadlet-list.1.md.in similarity index 99% rename from docs/source/markdown/podman-quadlet-list.1.md rename to docs/source/markdown/podman-quadlet-list.1.md.in index ed41ac1343..aa4c50e039 100644 --- a/docs/source/markdown/podman-quadlet-list.1.md +++ b/docs/source/markdown/podman-quadlet-list.1.md.in @@ -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 ``` diff --git a/test/system/253-podman-quadlet.bats b/test/system/253-podman-quadlet.bats index c5f1c47f2f..e07f0972cb 100644 --- a/test/system/253-podman-quadlet.bats +++ b/test/system/253-podman-quadlet.bats @@ -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 <