diff --git a/cmd/touch/touch.go b/cmd/touch/touch.go index d5f3f1e9a..b868784a6 100644 --- a/cmd/touch/touch.go +++ b/cmd/touch/touch.go @@ -61,7 +61,11 @@ time instead of the current time. Times may be specified as one of: - 'YYYY-MM-DDTHH:MM:SS.SSS' - e.g. 2006-01-02T15:04:05.123456789 Note that value of ` + "`--timestamp`" + ` is in UTC. If you want local time -then add the ` + "`--localtime`" + ` flag.`, +then add the ` + "`--localtime`" + ` flag. + +Metadata can be added when creating a new file with ` + "`--metadata-set`" + `. +For example: + rclone touch remote:path -M --metadata-set key=value`, Annotations: map[string]string{ "versionIntroduced": "v1.39", "groups": "Filter,Listing,Important", @@ -123,10 +127,10 @@ func timeOfTouch() (time.Time, error) { } // createEmptyObject creates an empty object (file) with specified timestamp -func createEmptyObject(ctx context.Context, remote string, modTime time.Time, f fs.Fs) error { +func createEmptyObject(ctx context.Context, remote string, modTime time.Time, f fs.Fs, options []fs.OpenOption) error { var buffer []byte src := object.NewStaticObjectInfo(remote, modTime, int64(len(buffer)), true, nil, f) - _, err := f.Put(ctx, bytes.NewBuffer(buffer), src) + _, err := f.Put(ctx, bytes.NewBuffer(buffer), src, options...) return err } @@ -163,7 +167,8 @@ func Touch(ctx context.Context, f fs.Fs, remote string) error { return nil } fs.Debugf(f, "Touching (creating) %q", remote) - if err = createEmptyObject(ctx, remote, t, f); err != nil { + options := fs.MetadataAsOpenOptions(ctx) + if err = createEmptyObject(ctx, remote, t, f, options); err != nil { return fmt.Errorf("failed to touch (create): %w", err) } } diff --git a/cmd/touch/touch_test.go b/cmd/touch/touch_test.go index 47e904549..40ff84e1b 100644 --- a/cmd/touch/touch_test.go +++ b/cmd/touch/touch_test.go @@ -150,3 +150,32 @@ func TestRecursiveTouchDirWithFiles(t *testing.T) { require.NoError(t, err) fstest.CheckListingWithPrecision(t, r.Fremote, []fstest.Item{file1, file2, file3}, []string{"a", "a/b", "a/b/c"}, fs.ModTimeNotSupported) } + +func TestTouchWithMetadata(t *testing.T) { + r := fstest.NewRun(t) + ctx := context.Background() + features := r.Fremote.Features() + if !features.UserMetadata { + t.Skip("Skipping metadata test; backend does not support user metadata") + } + + ci := fs.GetConfig(ctx) + origMetadata := ci.Metadata + origMetadataSet := ci.MetadataSet + t.Cleanup(func() { + ci.Metadata = origMetadata + ci.MetadataSet = origMetadataSet + }) + + ci.Metadata = true + ci.MetadataSet = fs.Metadata{ + "testkey": "testvalue", + } + + err := Touch(ctx, r.Fremote, "metaFile") + require.NoError(t, err) + + o, err := r.Fremote.NewObject(ctx, "metaFile") + require.NoError(t, err) + fstest.CheckEntryMetadata(ctx, t, r.Fremote, o, ci.MetadataSet) +}