diff --git a/commands/history/ls.go b/commands/history/ls.go
index 9153d8fca094..c79d73740058 100644
--- a/commands/history/ls.go
+++ b/commands/history/ls.go
@@ -18,6 +18,7 @@ import (
"github.com/docker/cli/cli"
"github.com/docker/cli/cli/command"
"github.com/docker/cli/cli/command/formatter"
+ cliflags "github.com/docker/cli/cli/flags"
"github.com/docker/go-units"
"github.com/pkg/errors"
"github.com/spf13/cobra"
@@ -31,7 +32,7 @@ const (
lsHeaderDuration = "DURATION"
lsHeaderLink = ""
- lsDefaultTableFormat = "table {{.Ref}}\t{{.Name}}\t{{.Status}}\t{{.CreatedAt}}\t{{.Duration}}\t{{.Link}}"
+ lsDefaultTableFormat = "table {{.BuildID}}\t{{.Name}}\t{{.Status}}\t{{.Created}}\t{{.Duration}}\t{{.Link}}"
headerKeyTimestamp = "buildkit-current-timestamp"
)
@@ -51,7 +52,7 @@ func runLs(ctx context.Context, dockerCli command.Cli, opts lsOptions) error {
return err
}
- queryOptions := &queryOptions{}
+ queryOpts := &queryOptions{}
if opts.local {
wd, err := os.Getwd()
@@ -69,11 +70,11 @@ func runLs(ctx context.Context, dockerCli command.Cli, opts lsOptions) error {
if err != nil {
return errors.Wrapf(err, "could not get remote URL for local filter")
}
- queryOptions.Filters = append(queryOptions.Filters, fmt.Sprintf("repository=%s", remote))
+ queryOpts.Filters = append(queryOpts.Filters, fmt.Sprintf("repository=%s", remote))
}
- queryOptions.Filters = append(queryOptions.Filters, opts.filters...)
+ queryOpts.Filters = append(queryOpts.Filters, opts.filters...)
- out, err := queryRecords(ctx, "", nodes, queryOptions)
+ out, err := queryRecords(ctx, "", nodes, queryOpts)
if err != nil {
return err
}
@@ -108,7 +109,7 @@ func lsCmd(dockerCli command.Cli, rootOpts RootOptions) *cobra.Command {
}
flags := cmd.Flags()
- flags.StringVar(&options.format, "format", formatter.TableFormatKey, "Format the output")
+ flags.StringVar(&options.format, "format", formatter.TableFormatKey, cliflags.FormatHelp)
flags.BoolVar(&options.noTrunc, "no-trunc", false, "Don't truncate output")
flags.StringArrayVar(&options.filters, "filter", nil, `Provide filter values (e.g., "status=error")`)
flags.BoolVar(&options.local, "local", false, "List records for current repository only")
@@ -144,10 +145,10 @@ func lsPrint(dockerCli command.Cli, records []historyRecord, in lsOptions) error
render := func(format func(subContext formatter.SubContext) error) error {
for _, r := range records {
if err := format(&lsContext{
- format: formatter.Format(in.format),
- isTerm: term,
- trunc: !in.noTrunc,
- record: &r,
+ format: formatter.Format(in.format),
+ isTerm: term,
+ trunc: !in.noTrunc,
+ historyRecord: &r,
}); err != nil {
return err
}
@@ -160,12 +161,12 @@ func lsPrint(dockerCli command.Cli, records []historyRecord, in lsOptions) error
trunc: !in.noTrunc,
}
lsCtx.Header = formatter.SubHeaderContext{
- "Ref": lsHeaderBuildID,
- "Name": lsHeaderName,
- "Status": lsHeaderStatus,
- "CreatedAt": lsHeaderCreated,
- "Duration": lsHeaderDuration,
- "Link": lsHeaderLink,
+ "BuildID": lsHeaderBuildID,
+ "Name": lsHeaderName,
+ "Status": lsHeaderStatus,
+ "Created": lsHeaderCreated,
+ "Duration": lsHeaderDuration,
+ "Link": lsHeaderLink,
}
return ctx.Write(&lsCtx, render)
@@ -177,7 +178,7 @@ type lsContext struct {
isTerm bool
trunc bool
format formatter.Format
- record *historyRecord
+ *historyRecord
}
func (c *lsContext) MarshalJSON() ([]byte, error) {
@@ -185,27 +186,27 @@ func (c *lsContext) MarshalJSON() ([]byte, error) {
"ref": c.FullRef(),
"name": c.Name(),
"status": c.Status(),
- "created_at": c.record.CreatedAt.AsTime().Format(time.RFC3339Nano),
- "total_steps": c.record.NumTotalSteps,
- "completed_steps": c.record.NumCompletedSteps,
- "cached_steps": c.record.NumCachedSteps,
+ "created_at": c.CreatedAt.AsTime().Format(time.RFC3339Nano),
+ "total_steps": c.NumTotalSteps,
+ "completed_steps": c.NumCompletedSteps,
+ "cached_steps": c.NumCachedSteps,
}
- if c.record.CompletedAt != nil {
- m["completed_at"] = c.record.CompletedAt.AsTime().Format(time.RFC3339Nano)
+ if c.CompletedAt != nil {
+ m["completed_at"] = c.CompletedAt.AsTime().Format(time.RFC3339Nano)
}
return json.Marshal(m)
}
-func (c *lsContext) Ref() string {
- return c.record.Ref
+func (c *lsContext) BuildID() string {
+ return c.Ref
}
func (c *lsContext) FullRef() string {
- return fmt.Sprintf("%s/%s/%s", c.record.node.Builder, c.record.node.Name, c.record.Ref)
+ return fmt.Sprintf("%s/%s/%s", c.node.Builder, c.node.Name, c.Ref)
}
func (c *lsContext) Name() string {
- name := c.record.name
+ name := c.name
if c.trunc && c.format.IsTable() {
return trimBeginning(name, 36)
}
@@ -213,8 +214,8 @@ func (c *lsContext) Name() string {
}
func (c *lsContext) Status() string {
- if c.record.CompletedAt != nil {
- if c.record.Error != nil {
+ if c.CompletedAt != nil {
+ if c.Error != nil {
return "Error"
}
return "Completed"
@@ -222,21 +223,21 @@ func (c *lsContext) Status() string {
return "Running"
}
-func (c *lsContext) CreatedAt() string {
- return units.HumanDuration(time.Since(c.record.CreatedAt.AsTime())) + " ago"
+func (c *lsContext) Created() string {
+ return units.HumanDuration(time.Since(c.CreatedAt.AsTime())) + " ago"
}
func (c *lsContext) Duration() string {
- lastTime := c.record.currentTimestamp
- if c.record.CompletedAt != nil {
- tm := c.record.CompletedAt.AsTime()
+ lastTime := c.currentTimestamp
+ if c.CompletedAt != nil {
+ tm := c.CompletedAt.AsTime()
lastTime = &tm
}
if lastTime == nil {
return ""
}
- v := formatDuration(lastTime.Sub(c.record.CreatedAt.AsTime()))
- if c.record.CompletedAt == nil {
+ v := formatDuration(lastTime.Sub(c.CreatedAt.AsTime()))
+ if c.CompletedAt == nil {
v += "+"
}
return v
diff --git a/docs/reference/buildx_history_ls.md b/docs/reference/buildx_history_ls.md
index 9f27d238df12..75bae00f4e07 100644
--- a/docs/reference/buildx_history_ls.md
+++ b/docs/reference/buildx_history_ls.md
@@ -9,14 +9,14 @@ List build records
### Options
-| Name | Type | Default | Description |
-|:--------------------------|:--------------|:--------|:---------------------------------------------|
-| `--builder` | `string` | | Override the configured builder instance |
-| `-D`, `--debug` | `bool` | | Enable debug logging |
-| [`--filter`](#filter) | `stringArray` | | Provide filter values (e.g., `status=error`) |
-| [`--format`](#format) | `string` | `table` | Format the output |
-| [`--local`](#local) | `bool` | | List records for current repository only |
-| [`--no-trunc`](#no-trunc) | `bool` | | Don't truncate output |
+| Name | Type | Default | Description |
+|:--------------------------|:--------------|:--------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| `--builder` | `string` | | Override the configured builder instance |
+| `-D`, `--debug` | `bool` | | Enable debug logging |
+| [`--filter`](#filter) | `stringArray` | | Provide filter values (e.g., `status=error`) |
+| [`--format`](#format) | `string` | `table` | Format output using a custom template:
'table': Print output in table format with column headers (default)
'table TEMPLATE': Print output in table format using the given Go template
'json': Print in JSON format
'TEMPLATE': Print output using the given Go template.
Refer to https://docs.docker.com/go/formatting/ for more information about formatting output with templates |
+| [`--local`](#local) | `bool` | | List records for current repository only |
+| [`--no-trunc`](#no-trunc) | `bool` | | Don't truncate output |