From 7a1cab57b60cedcd747d366d809a225b593ef324 Mon Sep 17 00:00:00 2001 From: Ivan Andreev Date: Thu, 7 Oct 2021 15:37:31 +0300 Subject: [PATCH] cmd/hashsum: dont put ERROR or UNSUPPORTED in output --- fs/operations/operations.go | 26 ++++++++++++++------------ fs/operations/operations_test.go | 28 ++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 12 deletions(-) diff --git a/fs/operations/operations.go b/fs/operations/operations.go index ed28543fe..4b5667d49 100644 --- a/fs/operations/operations.go +++ b/fs/operations/operations.go @@ -1000,9 +1000,10 @@ func hashSum(ctx context.Context, ht hash.Type, downloadFlag bool, o fs.Object) sum, err = o.Hash(ctx, ht) if err == hash.ErrUnsupported { - return "UNSUPPORTED", errors.Wrap(err, "Hash unsupported") - } else if err != nil { - return "ERROR", errors.Wrapf(err, "Failed to get hash %v from backed: %v", ht, err) + return "", errors.Wrap(err, "Hash unsupported") + } + if err != nil { + return "", errors.Wrapf(err, "Failed to get hash %v from backend: %v", ht, err) } } @@ -1013,6 +1014,10 @@ func hashSum(ctx context.Context, ht hash.Type, downloadFlag bool, o fs.Object) // Updated to handle both standard hex encoding and base64 // Updated to perform multiple hashes concurrently func HashLister(ctx context.Context, ht hash.Type, outputBase64 bool, downloadFlag bool, f fs.Fs, w io.Writer) error { + width := hash.Width(ht) + if outputBase64 { + width = base64.URLEncoding.EncodedLen(width / 2) + } concurrencyControl := make(chan struct{}, fs.GetConfig(ctx).Transfers) var wg sync.WaitGroup err := ListFn(ctx, f, func(o fs.Object) { @@ -1024,18 +1029,15 @@ func HashLister(ctx context.Context, ht hash.Type, outputBase64 bool, downloadFl wg.Done() }() sum, err := hashSum(ctx, ht, downloadFlag, o) - if outputBase64 && err == nil { + if err != nil { + fs.Errorf(o, "%v", fs.CountError(err)) + return + } + if outputBase64 { hexBytes, _ := hex.DecodeString(sum) sum = base64.URLEncoding.EncodeToString(hexBytes) - width := base64.URLEncoding.EncodedLen(hash.Width(ht) / 2) - syncFprintf(w, "%*s %s\n", width, sum, o.Remote()) - } else { - syncFprintf(w, "%*s %s\n", hash.Width(ht), sum, o.Remote()) - } - if err != nil { - err = fs.CountError(err) - fs.Errorf(o, "%v", err) } + syncFprintf(w, "%*s %s\n", width, sum, o.Remote()) }() }) wg.Wait() diff --git a/fs/operations/operations_test.go b/fs/operations/operations_test.go index 06883a7fe..4c43a66cd 100644 --- a/fs/operations/operations_test.go +++ b/fs/operations/operations_test.go @@ -43,6 +43,7 @@ import ( "github.com/rclone/rclone/fs/hash" "github.com/rclone/rclone/fs/operations" "github.com/rclone/rclone/fstest" + "github.com/rclone/rclone/fstest/fstests" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -330,6 +331,33 @@ func TestHashSums(t *testing.T) { } } +func TestHashSumsWithErrors(t *testing.T) { + ctx := context.Background() + memFs, err := fs.NewFs(ctx, ":memory:") + require.NoError(t, err) + + // Make a test file + content := "-" + item1 := fstest.NewItem("file1", content, t1) + _, _ = fstests.PutTestContents(ctx, t, memFs, &item1, content, true) + + // MemoryFS supports MD5 + buf := &bytes.Buffer{} + err = operations.HashLister(ctx, hash.MD5, false, false, memFs, buf) + require.NoError(t, err) + assert.Contains(t, buf.String(), "336d5ebc5436534e61d16e63ddfca327 file1\n") + + // MemoryFS can't do SHA1, but UNSUPPORTED must not appear in the output + buf.Reset() + err = operations.HashLister(ctx, hash.SHA1, false, false, memFs, buf) + require.NoError(t, err) + assert.NotContains(t, buf.String(), " UNSUPPORTED ") + + // ERROR must not appear in the output either + assert.NotContains(t, buf.String(), " ERROR ") + // TODO mock an unreadable file +} + func TestSuffixName(t *testing.T) { ctx := context.Background() ctx, ci := fs.AddConfig(ctx)