Add JSON stream progress writer

Signed-off-by: Felix Fontein <felix@fontein.de>
This commit is contained in:
Felix Fontein 2024-02-08 11:16:02 +01:00 коммит произвёл Nicolas De loof
Родитель 075fd93452
Коммит 06545d0668
6 изменённых файлов: 103 добавлений и 3 удалений

Просмотреть файл

@ -453,6 +453,8 @@ func RootCommand(dockerCli command.Cli, backend Backend) *cobra.Command { //noli
ui.Mode = ui.ModePlain
case ui.ModeQuiet, "none":
ui.Mode = ui.ModeQuiet
case ui.ModeJSON:
ui.Mode = ui.ModeJSON
default:
return fmt.Errorf("unsupported --progress value %q", opts.Progress)
}
@ -603,6 +605,7 @@ var printerModes = []string{
ui.ModeAuto,
ui.ModeTTY,
ui.ModePlain,
ui.ModeJSON,
ui.ModeQuiet,
}

Просмотреть файл

@ -51,7 +51,7 @@ Define and run multi-container applications with Docker
| `-f`, `--file` | `stringArray` | | Compose configuration files |
| `--parallel` | `int` | `-1` | Control max parallelism, -1 for unlimited |
| `--profile` | `stringArray` | | Specify a profile to enable |
| `--progress` | `string` | `auto` | Set type of progress output (auto, tty, plain, quiet) |
| `--progress` | `string` | `auto` | Set type of progress output (auto, tty, plain, json, quiet) |
| `--project-directory` | `string` | | Specify an alternate working directory<br>(default: the path of the, first specified, Compose file) |
| `-p`, `--project-name` | `string` | | Project name |

Просмотреть файл

@ -306,7 +306,7 @@ options:
- option: progress
value_type: string
default_value: auto
description: Set type of progress output (auto, tty, plain, quiet)
description: Set type of progress output (auto, tty, plain, json, quiet)
deprecated: false
hidden: false
experimental: false

Просмотреть файл

@ -99,7 +99,7 @@ options:
- option: progress
value_type: string
default_value: auto
description: Set type of ui output (auto, tty, plain, quiet)
description: Set type of ui output (auto, tty, plain, json, quiet)
deprecated: false
hidden: true
experimental: false

88
pkg/progress/json.go Normal file
Просмотреть файл

@ -0,0 +1,88 @@
/*
Copyright 2024 Docker Compose CLI authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package progress
import (
"context"
"encoding/json"
"fmt"
"io"
)
type jsonWriter struct {
out io.Writer
done chan bool
dryRun bool
}
type jsonMessage struct {
DryRun bool `json:"dry-run,omitempty"`
Tail bool `json:"tail,omitempty"`
ID string `json:"id,omitempty"`
Text string `json:"text,omitempty"`
Status string `json:"status,omitempty"`
}
func (p *jsonWriter) Start(ctx context.Context) error {
select {
case <-ctx.Done():
return ctx.Err()
case <-p.done:
return nil
}
}
func (p *jsonWriter) Event(e Event) {
var message = &jsonMessage{
DryRun: p.dryRun,
Tail: false,
ID: e.ID,
Text: e.Text,
Status: e.StatusText,
}
marshal, err := json.Marshal(message)
if err == nil {
fmt.Fprintln(p.out, string(marshal))
}
}
func (p *jsonWriter) Events(events []Event) {
for _, e := range events {
p.Event(e)
}
}
func (p *jsonWriter) TailMsgf(msg string, args ...interface{}) {
var message = &jsonMessage{
DryRun: p.dryRun,
Tail: true,
ID: "",
Text: fmt.Sprintf(msg, args...),
Status: "",
}
marshal, err := json.Marshal(message)
if err == nil {
fmt.Fprintln(p.out, string(marshal))
}
}
func (p *jsonWriter) Stop() {
p.done <- true
}
func (p *jsonWriter) HasMore(bool) {
}

Просмотреть файл

@ -107,6 +107,8 @@ const (
ModePlain = "plain"
// ModeQuiet don't display events
ModeQuiet = "quiet"
// ModeJSON outputs a machine-readable JSON stream
ModeJSON = "json"
)
// Mode define how progress should be rendered, either as ModePlain or ModeTTY
@ -130,6 +132,13 @@ func NewWriter(ctx context.Context, out *streams.Out, progressTitle string) (Wri
if tty {
return newTTYWriter(out, dryRun, progressTitle)
}
if Mode == ModeJSON {
return &jsonWriter{
out: out,
done: make(chan bool),
dryRun: dryRun,
}, nil
}
return &plainWriter{
out: out,
done: make(chan bool),