From ec237550245449802ff9d7d1a4b35c4550821dca Mon Sep 17 00:00:00 2001 From: Xiaoxuan Wang <103478229+wangxiaoxuan273@users.noreply.github.com> Date: Fri, 15 Mar 2024 14:48:58 +0800 Subject: [PATCH] fix: make --output - implies --no-tty (#1286) Signed-off-by: Xiaoxuan Wang --- cmd/oras/internal/option/common.go | 13 +++++++- cmd/oras/internal/option/common_test.go | 44 +++++++++++++++++++++++++ cmd/oras/root/blob/fetch.go | 6 +++- 3 files changed, 61 insertions(+), 2 deletions(-) diff --git a/cmd/oras/internal/option/common.go b/cmd/oras/internal/option/common.go index 7cb14a2c0..9cd7b622c 100644 --- a/cmd/oras/internal/option/common.go +++ b/cmd/oras/internal/option/common.go @@ -25,6 +25,8 @@ import ( "oras.land/oras/internal/trace" ) +const NoTTYFlag = "no-tty" + // Common option struct. type Common struct { Debug bool @@ -38,7 +40,7 @@ type Common struct { func (opts *Common) ApplyFlags(fs *pflag.FlagSet) { fs.BoolVarP(&opts.Debug, "debug", "d", false, "output debug logs (implies --no-tty)") fs.BoolVarP(&opts.Verbose, "verbose", "v", false, "verbose output") - fs.BoolVarP(&opts.noTTY, "no-tty", "", false, "[Preview] do not show progress output") + fs.BoolVarP(&opts.noTTY, NoTTYFlag, "", false, "[Preview] do not show progress output") } // WithContext returns a new FieldLogger and an associated Context derived from ctx. @@ -63,3 +65,12 @@ func (opts *Common) parseTTY(f *os.File) error { } return nil } + +// UpdateTTY updates the TTY value, given the status of --no-tty flag and output +// path value. +func (opts *Common) UpdateTTY(flagPresent bool, toSTDOUT bool) { + ttyEnforced := flagPresent && !opts.noTTY + if opts.noTTY || (toSTDOUT && !ttyEnforced) { + opts.TTY = nil + } +} diff --git a/cmd/oras/internal/option/common_test.go b/cmd/oras/internal/option/common_test.go index 6a035a820..2949fb448 100644 --- a/cmd/oras/internal/option/common_test.go +++ b/cmd/oras/internal/option/common_test.go @@ -16,6 +16,8 @@ limitations under the License. package option import ( + "os" + "reflect" "testing" "github.com/spf13/pflag" @@ -28,3 +30,45 @@ func TestCommon_FlagsInit(t *testing.T) { ApplyFlags(&test, pflag.NewFlagSet("oras-test", pflag.ExitOnError)) } + +func TestCommon_UpdateTTY(t *testing.T) { + testTTY := &os.File{} + tests := []struct { + name string + flagPresent bool + toSTDOUT bool + noTTY bool + expectedTTY *os.File + }{ + { + "output to STDOUT, --no-tty flag not used, reset TTY", false, true, false, nil, + }, + { + "output to STDOUT, --no-tty set to true, reset TTY", true, true, true, nil, + }, + { + "output to STDOUT, --no-tty set to false", true, true, false, testTTY, + }, + { + "not output to STDOUT, --no-tty flag not used", false, false, false, testTTY, + }, + { + "not output to STDOUT, --no-tty set to true, reset TTY", true, false, true, nil, + }, + { + "not output to STDOUT, --no-tty set to false", true, false, false, testTTY, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + opts := &Common{ + noTTY: tt.noTTY, + TTY: testTTY, + } + opts.UpdateTTY(tt.flagPresent, tt.toSTDOUT) + if !reflect.DeepEqual(opts.TTY, tt.expectedTTY) { + t.Fatalf("tt.TTY got %v, want %v", opts.TTY, tt.expectedTTY) + } + }) + } +} diff --git a/cmd/oras/root/blob/fetch.go b/cmd/oras/root/blob/fetch.go index 72cb3a256..f81c822fa 100644 --- a/cmd/oras/root/blob/fetch.go +++ b/cmd/oras/root/blob/fetch.go @@ -77,7 +77,11 @@ Example - Fetch and print a blob from OCI image layout archive file 'layout.tar' return errors.New("`--output -` cannot be used with `--descriptor` at the same time") } opts.RawReference = args[0] - return option.Parse(&opts) + err := option.Parse(&opts) + if err == nil { + opts.UpdateTTY(cmd.Flags().Changed(option.NoTTYFlag), opts.outputPath == "-") + } + return err }, Aliases: []string{"get"}, RunE: func(cmd *cobra.Command, args []string) error {