From 8fb9eb2feeda8d60039e07688998264cd71980af Mon Sep 17 00:00:00 2001 From: Nick Craig-Wood Date: Sun, 26 Mar 2023 16:55:03 +0100 Subject: [PATCH] sync: make --suffix-keep-extension preserve 2 part extensions like .tar.gz If a file has two (or more) extensions and the second (or subsequent) extension is recognised as a valid mime type, then the suffix will go before that extension. So `file.tar.gz` would be backed up to `file-2019-01-01.tar.gz` whereas `file.badextension.gz` would be backed up to `file.badextension-2019-01-01.gz` Fixes #6892 --- docs/content/docs.md | 6 ++++++ fs/operations/operations.go | 21 ++++++++++++++++++--- fs/operations/operations_test.go | 7 ++++++- 3 files changed, 30 insertions(+), 4 deletions(-) diff --git a/docs/content/docs.md b/docs/content/docs.md index 9084a7b26..a23ec18f8 100644 --- a/docs/content/docs.md +++ b/docs/content/docs.md @@ -1840,6 +1840,12 @@ would be backed up to `file.txt-2019-01-01` and with the flag it would be backed up to `file-2019-01-01.txt`. This can be helpful to make sure the suffixed files can still be opened. +If a file has two (or more) extensions and the second (or subsequent) +extension is recognised as a valid mime type, then the suffix will go +before that extension. So `file.tar.gz` would be backed up to +`file-2019-01-01.tar.gz` whereas `file.badextension.gz` would be +backed up to `file.badextension-2019-01-01.gz`. + ### --syslog ### On capable OSes (not Windows or Plan9) send all log output to syslog. diff --git a/fs/operations/operations.go b/fs/operations/operations.go index 55a24a2d0..3f6fb6e73 100644 --- a/fs/operations/operations.go +++ b/fs/operations/operations.go @@ -618,9 +618,24 @@ func SuffixName(ctx context.Context, remote string) string { return remote } if ci.SuffixKeepExtension { - ext := path.Ext(remote) - base := remote[:len(remote)-len(ext)] - return base + ci.Suffix + ext + var ( + base = remote + exts = "" + first = true + ext = path.Ext(remote) + ) + for ext != "" { + // Look second and subsequent extensions in mime types. + // If they aren't found then don't keep it as an extension. + if !first && mime.TypeByExtension(ext) == "" { + break + } + base = base[:len(base)-len(ext)] + exts = ext + exts + first = false + ext = path.Ext(base) + } + return base + ci.Suffix + exts } return remote + ci.Suffix } diff --git a/fs/operations/operations_test.go b/fs/operations/operations_test.go index 37ebe99c4..45a2259be 100644 --- a/fs/operations/operations_test.go +++ b/fs/operations/operations_test.go @@ -371,9 +371,14 @@ func TestSuffixName(t *testing.T) { {"test.txt", "-suffix", false, "test.txt-suffix"}, {"test.txt", "-suffix", true, "test-suffix.txt"}, {"test.txt.csv", "-suffix", false, "test.txt.csv-suffix"}, - {"test.txt.csv", "-suffix", true, "test.txt-suffix.csv"}, + {"test.txt.csv", "-suffix", true, "test-suffix.txt.csv"}, {"test", "-suffix", false, "test-suffix"}, {"test", "-suffix", true, "test-suffix"}, + {"test.html", "-suffix", true, "test-suffix.html"}, + {"test.html.txt", "-suffix", true, "test-suffix.html.txt"}, + {"test.csv.html.txt", "-suffix", true, "test-suffix.csv.html.txt"}, + {"test.badext.csv.html.txt", "-suffix", true, "test.badext-suffix.csv.html.txt"}, + {"test.badext", "-suffix", true, "test-suffix.badext"}, } { ci.Suffix = test.suffix ci.SuffixKeepExtension = test.keepExt