diff --git a/backend/local/local.go b/backend/local/local.go index 1a96d8036..242656c92 100644 --- a/backend/local/local.go +++ b/backend/local/local.go @@ -34,7 +34,6 @@ import ( // Constants const ( devUnset = 0xdeadbeefcafebabe // a device id meaning it is unset - linkSuffix = ".rclonelink" // The suffix added to a translated symbolic link useReadDir = (runtime.GOOS == "windows" || runtime.GOOS == "plan9") // these OSes read FileInfos directly ) @@ -101,7 +100,7 @@ Metadata is supported on files and directories. }, { Name: "links", - Help: "Translate symlinks to/from regular files with a '" + linkSuffix + "' extension.", + Help: "Translate symlinks to/from regular files with a '" + fs.LinkSuffix + "' extension.", Default: false, NoPrefix: true, ShortOpt: "l", @@ -379,7 +378,7 @@ type Directory struct { var ( errLinksAndCopyLinks = errors.New("can't use -l/--links with -L/--copy-links") - errLinksNeedsSuffix = errors.New("need \"" + linkSuffix + "\" suffix to refer to symlink when using -l/--links") + errLinksNeedsSuffix = errors.New("need \"" + fs.LinkSuffix + "\" suffix to refer to symlink when using -l/--links") ) // NewFs constructs an Fs from the path @@ -435,9 +434,9 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e f.dev = readDevice(fi, f.opt.OneFileSystem) } // Check to see if this is a .rclonelink if not found - hasLinkSuffix := strings.HasSuffix(f.root, linkSuffix) + hasLinkSuffix := strings.HasSuffix(f.root, fs.LinkSuffix) if hasLinkSuffix && opt.TranslateSymlinks && os.IsNotExist(err) { - fi, err = f.lstat(strings.TrimSuffix(f.root, linkSuffix)) + fi, err = f.lstat(strings.TrimSuffix(f.root, fs.LinkSuffix)) } if err == nil && f.isRegular(fi.Mode()) { // Handle the odd case, that a symlink was specified by name without the link suffix @@ -508,8 +507,8 @@ func (f *Fs) caseInsensitive() bool { // // for regular files, localPath is returned unchanged func translateLink(remote, localPath string) (newLocalPath string, isTranslatedLink bool) { - isTranslatedLink = strings.HasSuffix(remote, linkSuffix) - newLocalPath = strings.TrimSuffix(localPath, linkSuffix) + isTranslatedLink = strings.HasSuffix(remote, fs.LinkSuffix) + newLocalPath = strings.TrimSuffix(localPath, fs.LinkSuffix) return newLocalPath, isTranslatedLink } @@ -692,7 +691,7 @@ func (f *Fs) List(ctx context.Context, dir string) (entries fs.DirEntries, err e } else { // Check whether this link should be translated if f.opt.TranslateSymlinks && fi.Mode()&os.ModeSymlink != 0 { - newRemote += linkSuffix + newRemote += fs.LinkSuffix } // Don't include non directory if not included // we leave directory filtering to the layer above diff --git a/backend/local/local_internal_test.go b/backend/local/local_internal_test.go index b3b9b8ba1..4c769535e 100644 --- a/backend/local/local_internal_test.go +++ b/backend/local/local_internal_test.go @@ -110,7 +110,7 @@ func TestSymlink(t *testing.T) { require.NoError(t, lChtimes(symlinkPath, modTime2, modTime2)) // Object viewed as symlink - file2 := fstest.NewItem("symlink.txt"+linkSuffix, "file.txt", modTime2) + file2 := fstest.NewItem("symlink.txt"+fs.LinkSuffix, "file.txt", modTime2) // Object viewed as destination file2d := fstest.NewItem("symlink.txt", "hello", modTime1) @@ -139,7 +139,7 @@ func TestSymlink(t *testing.T) { // Create a symlink modTime3 := fstest.Time("2002-03-03T04:05:10.123123123Z") - file3 := r.WriteObjectTo(ctx, r.Flocal, "symlink2.txt"+linkSuffix, "file.txt", modTime3, false) + file3 := r.WriteObjectTo(ctx, r.Flocal, "symlink2.txt"+fs.LinkSuffix, "file.txt", modTime3, false) fstest.CheckListingWithPrecision(t, r.Flocal, []fstest.Item{file1, file2, file3}, nil, fs.ModTimeNotSupported) if haveLChtimes { r.CheckLocalItems(t, file1, file2, file3) @@ -155,9 +155,9 @@ func TestSymlink(t *testing.T) { assert.Equal(t, "file.txt", linkText) // Check that NewObject gets the correct object - o, err := r.Flocal.NewObject(ctx, "symlink2.txt"+linkSuffix) + o, err := r.Flocal.NewObject(ctx, "symlink2.txt"+fs.LinkSuffix) require.NoError(t, err) - assert.Equal(t, "symlink2.txt"+linkSuffix, o.Remote()) + assert.Equal(t, "symlink2.txt"+fs.LinkSuffix, o.Remote()) assert.Equal(t, int64(8), o.Size()) // Check that NewObject doesn't see the non suffixed version @@ -165,7 +165,7 @@ func TestSymlink(t *testing.T) { require.Equal(t, fs.ErrorObjectNotFound, err) // Check that NewFs works with the suffixed version and --links - f2, err := NewFs(ctx, "local", filepath.Join(dir, "symlink2.txt"+linkSuffix), configmap.Simple{ + f2, err := NewFs(ctx, "local", filepath.Join(dir, "symlink2.txt"+fs.LinkSuffix), configmap.Simple{ "links": "true", }) require.Equal(t, fs.ErrorIsFile, err) @@ -277,7 +277,7 @@ func TestMetadata(t *testing.T) { // Write a symlink to the file symlinkPath := "metafile-link.txt" osSymlinkPath := filepath.Join(f.root, symlinkPath) - symlinkPath += linkSuffix + symlinkPath += fs.LinkSuffix require.NoError(t, os.Symlink(filePath, osSymlinkPath)) symlinkModTime := fstest.Time("2002-02-03T04:05:10.123123123Z") require.NoError(t, lChtimes(osSymlinkPath, symlinkModTime, symlinkModTime)) diff --git a/fs/fs.go b/fs/fs.go index fe68517c4..83b03f474 100644 --- a/fs/fs.go +++ b/fs/fs.go @@ -16,6 +16,8 @@ const ( ModTimeNotSupported = 100 * 365 * 24 * time.Hour // MaxLevel is a sentinel representing an infinite depth for listings MaxLevel = math.MaxInt32 + // The suffix added to a translated symbolic link + LinkSuffix = ".rclonelink" ) // Globals