From 9872921496ae2bde8b8abc2f4645258cd9153c5f Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Mon, 6 Jul 2026 12:28:14 +0200 Subject: [PATCH] cmd/prompt: remove uses of github.com/AlecAivazis/survey/v2 The github.com/AlecAivazis/survey/v2 module was archived and is no longer maintained. Looking at the code, we didn't really use most of its features; survey mostly provided terminal input handling around a simple yes/no question. Replace the interactive confirmation implementation with a small local prompt reader while keeping the exported prompt types and existing non-terminal prompt behavior unchanged. Preserve the confirmation hint, default handling, retries for invalid input, and Ctrl+C handling. Interactive prompts continue to use raw terminal input so Ctrl+C is handled by the prompt instead of requiring a second interrupt to terminate the process. Signed-off-by: Sebastiaan van Stijn --- cmd/compose/options.go | 4 +- cmd/compose/options_test.go | 4 +- cmd/prompt/prompt.go | 109 +++++++++++------- cmd/prompt/prompt_test.go | 219 ++++++++++++++++++++++++++++++++++++ go.mod | 6 - go.sum | 44 -------- 6 files changed, 294 insertions(+), 92 deletions(-) create mode 100644 cmd/prompt/prompt_test.go diff --git a/cmd/compose/options.go b/cmd/compose/options.go index b639afabde1..9fa089882db 100644 --- a/cmd/compose/options.go +++ b/cmd/compose/options.go @@ -162,7 +162,7 @@ func promptForInterpolatedVariables(ctx context.Context, dockerCli command.Cli, // Prompt for confirmation userInput := prompt.NewPrompt(dockerCli.In(), dockerCli.Out()) - msg := "\nDo you want to proceed with these variables? [Y/n]: " + msg := "\nDo you want to proceed with these variables?" confirmed, err := userInput.Confirm(msg, true) if err != nil { return err @@ -286,7 +286,7 @@ func confirmRemoteIncludes(dockerCli command.Cli, options buildOptions, assumeYe } _, _ = fmt.Fprintln(dockerCli.Out(), "\nRemote includes could potentially be malicious. Make sure you trust the source.") - msg := "Do you want to continue? [y/N]: " + msg := "Do you want to continue?" confirmed, err := prompt.NewPrompt(dockerCli.In(), dockerCli.Out()).Confirm(msg, false) if err != nil { return err diff --git a/cmd/compose/options_test.go b/cmd/compose/options_test.go index 13a33d7994c..c015a7a7238 100644 --- a/cmd/compose/options_test.go +++ b/cmd/compose/options_test.go @@ -403,7 +403,7 @@ func TestConfirmRemoteIncludes(t *testing.T) { " - oci://registry.example.com/stack:latest\n" + " - git://github.com/user/repo.git\n" + "\nRemote includes could potentially be malicious. Make sure you trust the source.\n" + - "Do you want to continue? [y/N]: ", + "Do you want to continue?", }, { name: "user rejects remote includes", @@ -422,7 +422,7 @@ func TestConfirmRemoteIncludes(t *testing.T) { wantOutput: "\nWarning: This Compose project includes files from remote sources:\n" + " - oci://registry.example.com/stack:latest\n" + "\nRemote includes could potentially be malicious. Make sure you trust the source.\n" + - "Do you want to continue? [y/N]: ", + "Do you want to continue?", }, } diff --git a/cmd/prompt/prompt.go b/cmd/prompt/prompt.go index 87379f5eb61..e7d75cc7946 100644 --- a/cmd/prompt/prompt.go +++ b/cmd/prompt/prompt.go @@ -17,10 +17,13 @@ package prompt import ( + "bufio" + "errors" "fmt" "io" + "strings" + "unicode" - "github.com/AlecAivazis/survey/v2" "github.com/docker/cli/cli/streams" "github.com/docker/compose/v5/pkg/utils" @@ -28,6 +31,8 @@ import ( //go:generate mockgen -destination=./prompt_mock.go -self_package "github.com/docker/compose/v5/pkg/prompt" -package=prompt . UI +var errInterrupt = errors.New("interrupt") + // UI - prompt user input type UI interface { Confirm(message string, defaultValue bool) (bool, error) @@ -35,56 +40,84 @@ type UI interface { func NewPrompt(stdin *streams.In, stdout *streams.Out) UI { if stdin.IsTerminal() { - return User{stdin: streamsFileReader{stdin}, stdout: streamsFileWriter{stdout}} + return User{stdin: stdin, reader: bufio.NewReader(stdin), stdout: stdout} } return Pipe{stdin: stdin, stdout: stdout} } // User - in a terminal type User struct { - stdout streamsFileWriter - stdin streamsFileReader -} - -// adapt streams.Out to terminal.FileWriter -type streamsFileWriter struct { - stream *streams.Out -} - -func (s streamsFileWriter) Write(p []byte) (n int, err error) { - return s.stream.Write(p) -} - -func (s streamsFileWriter) Fd() uintptr { - return s.stream.FD() + stdout io.Writer + stdin *streams.In + reader *bufio.Reader } -// adapt streams.In to terminal.FileReader -type streamsFileReader struct { - stream *streams.In -} +// Confirm asks for yes or no input +func (u User) Confirm(message string, defaultValue bool) (bool, error) { + if err := u.stdin.SetRawTerminal(); err != nil { + return false, err + } + defer u.stdin.RestoreTerminal() -func (s streamsFileReader) Read(p []byte) (n int, err error) { - return s.stream.Read(p) -} + prompt := " [y/N]: " + if defaultValue { + prompt = " [Y/n]: " + } -func (s streamsFileReader) Fd() uintptr { - return s.stream.FD() + for { + _, _ = fmt.Fprint(u.stdout, message+prompt) + + answer, err := readLine(u.reader, u.stdout) + if err != nil { + return false, err + } + + switch strings.ToLower(strings.TrimSpace(answer)) { + case "": + return defaultValue, nil + case "y", "yes": + return true, nil + case "n", "no": + return false, nil + } + } } -// Confirm asks for yes or no input -func (u User) Confirm(message string, defaultValue bool) (bool, error) { - qs := &survey.Confirm{ - Message: message, - Default: defaultValue, +func readLine(in io.RuneReader, out io.Writer) (string, error) { + var line []rune + + for { + ch, _, err := in.ReadRune() + if err != nil { + return "", err + } + + switch ch { + case 3: // Ctrl+C + _, _ = fmt.Fprint(out, "\r\n") + return "", errInterrupt + + case 4: // Ctrl+D + return "", io.EOF + + case '\r', '\n': + _, _ = fmt.Fprint(out, "\r\n") + return string(line), nil + + case 127: // Backspace + if len(line) > 0 { + line = line[:len(line)-1] + _, _ = fmt.Fprint(out, "\b \b") + } + + default: + if unicode.IsControl(ch) { + continue + } + line = append(line, ch) + _, _ = fmt.Fprintf(out, "%c", ch) + } } - var b bool - err := survey.AskOne(qs, &b, func(options *survey.AskOptions) error { - options.Stdio.In = u.stdin - options.Stdio.Out = u.stdout - return nil - }) - return b, err } // Pipe - aggregates prompt methods diff --git a/cmd/prompt/prompt_test.go b/cmd/prompt/prompt_test.go new file mode 100644 index 00000000000..1072d5e9613 --- /dev/null +++ b/cmd/prompt/prompt_test.go @@ -0,0 +1,219 @@ +/* + Copyright 2020 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 prompt + +import ( + "bufio" + "bytes" + "io" + "os" + "strings" + "testing" + "time" + + "github.com/creack/pty" + "github.com/docker/cli/cli/streams" + "gotest.tools/v3/assert" +) + +// TestPipeConfirmSequential verifies consecutive piped confirmations consume +// one line of input at a time. +func TestPipeConfirmSequential(t *testing.T) { + var stdout bytes.Buffer + pipe := Pipe{ + stdin: strings.NewReader("y\nn\n"), + stdout: &stdout, + } + + got, err := pipe.Confirm("first? ", false) + assert.NilError(t, err) + assert.Assert(t, got) + + got, err = pipe.Confirm("second? ", true) + assert.NilError(t, err) + assert.Assert(t, !got) +} + +// TestUserConfirm verifies that an interactive terminal confirmation returns +// the expected answer and retries invalid input. +func TestUserConfirm(t *testing.T) { + ptmx, user := newTestUser(t) + + done := make(chan struct { + answer bool + err error + }, 1) + + go func() { + answer, err := user.Confirm("Continue?", false) + done <- struct { + answer bool + err error + }{answer, err} + }() + + readUntil(t, ptmx, "Continue? [y/N]: ") + + _, err := ptmx.Write([]byte("maybe\r")) + assert.NilError(t, err) + + readUntil(t, ptmx, "Continue? [y/N]: ") + + // Surrounding whitespace is ignored. + _, err = ptmx.Write([]byte(" y \r")) + assert.NilError(t, err) + + select { + case result := <-done: + assert.NilError(t, result.err) + assert.Assert(t, result.answer) + case <-time.After(time.Second): + t.Fatal("timed out waiting for prompt to return") + } +} + +// TestUserConfirmDefault verifies that an empty answer selects the default. +func TestUserConfirmDefault(t *testing.T) { + ptmx, user := newTestUser(t) + + done := make(chan struct { + answer bool + err error + }, 1) + + go func() { + answer, err := user.Confirm("Continue?", true) + done <- struct { + answer bool + err error + }{answer, err} + }() + + readUntil(t, ptmx, "Continue? [Y/n]: ") + + _, err := ptmx.Write([]byte{'\r'}) + assert.NilError(t, err) + + select { + case result := <-done: + assert.NilError(t, result.err) + assert.Assert(t, result.answer) + case <-time.After(time.Second): + t.Fatal("timed out waiting for prompt to return") + } +} + +// TestUserConfirmSequential verifies consecutive confirmations consume +// one line of input at a time. +func TestUserConfirmSequential(t *testing.T) { + ptmx, user := newTestUser(t) + + done := make(chan struct { + first, second bool + err error + }, 1) + go func() { + first, err := user.Confirm("first?", false) + if err != nil { + done <- struct { + first, second bool + err error + }{err: err} + return + } + second, err := user.Confirm("second?", true) + done <- struct { + first, second bool + err error + }{first, second, err} + }() + + readUntil(t, ptmx, "first? [y/N]: ") + _, err := ptmx.Write([]byte("y\r")) + assert.NilError(t, err) + + readUntil(t, ptmx, "second? [Y/n]: ") + _, err = ptmx.Write([]byte("n\r")) + assert.NilError(t, err) + + select { + case result := <-done: + assert.NilError(t, result.err) + assert.Assert(t, result.first) + assert.Assert(t, !result.second) + case <-time.After(time.Second): + t.Fatal("timed out waiting for prompts to return") + } +} + +func TestReadLineInterrupt(t *testing.T) { + var stdout bytes.Buffer + + _, err := readLine( + bufio.NewReader(strings.NewReader("\x03")), + &stdout, + ) + + assert.ErrorIs(t, err, errInterrupt) + assert.Equal(t, stdout.String(), "\r\n") +} + +func newTestUser(t *testing.T) (*os.File, User) { + t.Helper() + + ptmx, tty, err := pty.Open() + assert.NilError(t, err) + t.Cleanup(func() { + _ = tty.Close() + _ = ptmx.Close() + }) + + stdin := streams.NewIn(tty) + return ptmx, User{stdin: stdin, reader: bufio.NewReader(stdin), stdout: streams.NewOut(tty)} +} + +// readUntil reads until the expected string is observed. +func readUntil(t *testing.T, r io.Reader, want string) { + t.Helper() + + type result struct { + got string + err error + } + + done := make(chan result, 1) + go func() { + var got strings.Builder + buf := make([]byte, 64) + for !strings.Contains(got.String(), want) { + n, err := r.Read(buf) + if err != nil { + done <- result{got: got.String(), err: err} + return + } + got.Write(buf[:n]) + } + done <- result{got: got.String()} + }() + + select { + case res := <-done: + assert.NilError(t, res.err, "reading until %q; got %q", want, res.got) + case <-time.After(time.Second): + t.Fatalf("timed out reading until %q", want) + } +} diff --git a/go.mod b/go.mod index f77dedba235..718ad3b507d 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,6 @@ module github.com/docker/compose/v5 go 1.26.3 require ( - github.com/AlecAivazis/survey/v2 v2.3.7 github.com/DefangLabs/secret-detector v0.0.0-20250403165618-22662109213e github.com/Microsoft/go-winio v0.6.3-0.20251027160822-ad3df93bed29 github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d @@ -89,11 +88,7 @@ require ( github.com/in-toto/in-toto-golang v0.11.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/inhies/go-bytesize v0.0.0-20220417184213-4913239db9cf // indirect - github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect github.com/klauspost/compress v1.19.2 // indirect - github.com/mattn/go-colorable v0.1.14 // indirect - github.com/mattn/go-isatty v0.0.20 // indirect - github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect github.com/moby/docker-image-spec v1.3.1 // indirect github.com/moby/locker v1.0.1 // indirect github.com/moby/sys/capability v0.4.0 // indirect @@ -126,7 +121,6 @@ require ( go.yaml.in/yaml/v3 v3.0.5 // indirect golang.org/x/crypto v0.56.0 // indirect golang.org/x/net v0.58.0 // indirect - golang.org/x/term v0.45.0 // indirect golang.org/x/text v0.41.0 // indirect golang.org/x/time v0.15.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20260825221802-da73d73af1c5 // indirect diff --git a/go.sum b/go.sum index 89db4b14e58..af95dc5eb9a 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,5 @@ github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6 h1:He8afgbRMd7mFxO99hRNu+6tazq8nFF9lIwo9JFroBk= github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8= -github.com/AlecAivazis/survey/v2 v2.3.7 h1:6I/u8FvytdGsgonrYsVn2t8t4QiRnh6QSTqkkhIiSjQ= -github.com/AlecAivazis/survey/v2 v2.3.7/go.mod h1:xUTIdE4KCOIjsBAE1JYsUPoCqYdZ1reCfTwbto0Fduo= github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c h1:udKWzYgxTojEKWjV8V+WSxDXJ4NFATAsZjh8iIbsQIg= github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/DefangLabs/secret-detector v0.0.0-20250403165618-22662109213e h1:rd4bOvKmDIx0WeTv9Qz+hghsgyjikFiPrseXHlKepO0= @@ -10,8 +8,6 @@ github.com/Microsoft/go-winio v0.6.3-0.20251027160822-ad3df93bed29 h1:0kQAzHq8vL github.com/Microsoft/go-winio v0.6.3-0.20251027160822-ad3df93bed29/go.mod h1:ZWa7ssZJT30CCDGJ7fk/2SBTq9BIQrrVjrcss0UW2s0= github.com/Microsoft/hcsshim v0.15.0-rc.4 h1:aZFX4LH0S20Lgjq0wG61StIClj7im4yzrxIClkaR8Z8= github.com/Microsoft/hcsshim v0.15.0-rc.4/go.mod h1:BA9CBztgu4h/6Jsvo1O1M4qjWw09PoYpaEYgexPE578= -github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2 h1:+vx7roKuyA63nhn5WAunQHLTznkw5W8b1Xc0dNjp83s= -github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2/go.mod h1:HBCaDeC1lPdgDeDbhX8XFpy1jqjK0IBG8W5K+xYqA0w= github.com/ProtonMail/go-crypto v1.4.1 h1:9RfcZHqEQUvP8RzecWEUafnZVtEvrBVL9BiF67IQOfM= github.com/ProtonMail/go-crypto v1.4.1/go.mod h1:e1OaTyu5SYVrO9gKOEhTc+5UcXtTUa+P3uLudwcgPqo= github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d h1:licZJFw2RwpHMqeKTCYkitsPqHNxTmd4SNR5r94FGM8= @@ -68,7 +64,6 @@ github.com/containerd/typeurl/v2 v2.3.0/go.mod h1:Qk+PAdUYArVj41TnGi6rJ+48RF0Pkc github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= github.com/cpuguy83/go-md2man/v2 v2.0.7 h1:zbFlGlXEAKlwXpmvle3d8Oe3YnkKIK4xSRTd3sHPnBo= github.com/cpuguy83/go-md2man/v2 v2.0.7/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= -github.com/creack/pty v1.1.17/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= github.com/creack/pty v1.1.24 h1:bJrF4RRfyJnbTJqzRLHzcGaZK1NeM5kTC9jGgovnR1s= github.com/creack/pty v1.1.24/go.mod h1:08sCNb52WyoAwi2QDyzUCTgcvVFhUzewun7wtTfvcwE= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -129,8 +124,6 @@ github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+l github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/hashicorp/go-version v1.9.0 h1:CeOIz6k+LoN3qX9Z0tyQrPtiB1DFYRPfCIBtaXPSCnA= github.com/hashicorp/go-version v1.9.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec h1:qv2VnGeEQHchGaZ/u7lxST/RaJw+cv273q79D81Xbog= -github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec/go.mod h1:Q48J4R4DvxnHolD5P8pOtXigYlRuPLGl6moFx3ulM68= github.com/in-toto/attestation v1.2.0 h1:aPRUZ3azbqD7yEBD5fP3TD8Dszf+YHo284SOcpahjQk= github.com/in-toto/attestation v1.2.0/go.mod h1:r79G45gOmzPismgObLSL+rZTFxUgZLOQJI6LofTZgXk= github.com/in-toto/in-toto-golang v0.11.0 h1:nfidMYBFx+E0lnmX5KUnN2Pdm8zdNKal1ayjJuzzRoA= @@ -139,26 +132,16 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/inhies/go-bytesize v0.0.0-20220417184213-4913239db9cf h1:FtEj8sfIcaaBfAKrE1Cwb61YDtYq9JxChK1c7AKce7s= github.com/inhies/go-bytesize v0.0.0-20220417184213-4913239db9cf/go.mod h1:yrqSXGoD/4EKfF26AOGzscPOgTTJcyAwM2rpixWT+t4= -github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= -github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= github.com/klauspost/compress v1.19.2 h1:hMRETovs/pu/dVWN7zIT1PGG8t509MwT6bO7XSi26R8= github.com/klauspost/compress v1.19.2/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= -github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= -github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= -github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.23 h1:7ykA0T0jkPpzSvMS5i9uoNn2Xy3R383f9HDx3RybWcw= github.com/mattn/go-runewidth v0.0.23/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs= github.com/mattn/go-shellwords v1.0.14 h1:yUKzIgsCnosndOASY6/enly1EAuaXeFSQ7cdyA3OuYg= github.com/mattn/go-shellwords v1.0.14/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y= -github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1fWh90gTKwiN4QCGoY9TWyyO4= -github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= github.com/mitchellh/go-ps v1.0.0 h1:i6ampVEEF4wQFF+bkYfwYgY+F/uYJDktmvLPf7qIgjc= github.com/mitchellh/go-ps v1.0.0/go.mod h1:J4lOc8z8yJs6vUwklHw2XEIiT4z4C40KtWVN3nvg8Pg= github.com/moby/buildkit v0.33.0 h1:zBbt1FiMcTB/oFg1iCNcKa83k5Rn8MGcVjXFIcfYhuQ= @@ -258,7 +241,6 @@ github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSS github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= @@ -281,7 +263,6 @@ github.com/xhit/go-str2duration/v2 v2.1.0 h1:lxklc02Drh6ynqX+DdPyp5pCKLUQpRT8bp8 github.com/xhit/go-str2duration/v2 v2.1.0/go.mod h1:ohY8p+0f07DiV6Em5LKB0s2YpLtXVyJfNt1+BlmyAsU= github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 h1:ilQV1hzziu+LLM3zUTJ0trRztfwgjqKnBWNtSRkbmwM= github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78/go.mod h1:aL8wCCfTfSfmXjznFBSZNN13rSJjlIOI1fUNAtF7rmI= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.71.0 h1:B2h3uqicet1CT2N5TOFhS+Gq++9i0/CLmaxvhmhtP5s= @@ -323,51 +304,26 @@ go.yaml.in/yaml/v3 v3.0.5 h1:N6y/pJk8buWs9NY5ERU2HSMfm+IuD/OtfdAnq6kESPw= go.yaml.in/yaml/v3 v3.0.5/go.mod h1:HVTZu1O7/Vkt2N+BFy8Zza+lnLsABggaTM2ZpNIGuKg= go.yaml.in/yaml/v4 v4.0.0-rc.6 h1:1h7H1ohdUh93/FyE4YaDa1Zh64K6VVbjF4K6WUxMtH4= go.yaml.in/yaml/v4 v4.0.0-rc.6/go.mod h1:aZqd9kCMsGL7AuUv/m/PvWLdg5sjJsZ4oHDEnfPPfY0= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.56.0 h1:GUh5Ii4J5jtcseSMiRqr1jXCNHoxjeV9Fmekc2oLy6Y= golang.org/x/crypto v0.56.0/go.mod h1:OMW5y6CY9l38uPLmxU6l6pwcXp1obtLo3e6gT7gQR2I= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.40.0 h1:hUv+3cXcdRHz08UmSiOob7sadHig73uo5bkXxQ/tvUs= golang.org/x/mod v0.40.0/go.mod h1:0/weTWkPWGBikyTWAX3dkjVztMmBA5hM0DH6BElSupE= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.58.0 h1:ynWG7rqYi4ccpTEuPZ2QGWHktVEM9DMCj9yzDE0Q7To= golang.org/x/net v0.58.0/go.mod h1:YwCddHnFlT7eLQqVprV19OnhLGtc5xOKgE0RyqgfWAU= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.22.0 h1:SZjpbeLmrCk4xhRSZFNZW5gFUeCeFgjekvI/+gfScek= golang.org/x/sync v0.22.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210331175145-43e1dd70ce54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.48.0 h1:bbX/i/6MgT9BVLM9RT1thmxL04yeTAhbEz4SyadbXoo= golang.org/x/sys v0.48.0/go.mod h1:hNLxWAXmnKAxqDtdwIYC4bM9oQPEecfsnNMuSxOs3og= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.45.0 h1:NwWyBmoJCbfTHpxrWoZ9C6/VxOf7ic219I8xZZFdrf0= golang.org/x/term v0.45.0/go.mod h1:9aqxs0blBcrm/n0L9QW0aRVD+ktan8ssZromtqJC43w= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.41.0 h1:vz/seA0lnX87Othu2f/0L24RcgrXD9/YFTSuGjj3rH8= golang.org/x/text v0.41.0/go.mod h1:jvf1O8ajNzZqhSrQBPbutR/EB83Cc0CFrezNQIwbb5M= golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U= golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E= google.golang.org/genproto/googleapis/api v0.0.0-20260825221802-da73d73af1c5 h1:izFU9hz7aeLI/Mi1J0991ae+xcwRLr7hTqWnB/9aIIU=