builder/remotecontext: Deprecate Rel()

This function was added in 684633f734, because
Go stdlib's filepath.Rel did not support Windows UUID paths (and UNC paths).

UNC paths were fixed in https://golang.org/cl/253197 (go1.17), and I think
UUID paths were also supported now.

To verify the behavior I temporarily added a unit-test to compare between
stdlib and this implementation, and it all looks to work, so we can deprecate
and remove this function. Deprecating first, but there's no (known) external
users of this, so we can likely remove in an upcoming minor (or patch) release.

    func TestRel(t *testing.T) {
        testCases := []struct {
            doc      string
            base     string
            target   string
            expected string
        }{
            {
                doc:      "UNC path",
                base:     `\\server\share`,
                target:   `\\server\share\folder\file.txt`,
                expected: `folder\file.txt`,
            },
            {
                doc:      "UUID path",
                base:     `\\?\Volume{b75e2c83-0000-0000-0000-602f00000000}\data`,
                target:   `\\?\Volume{b75e2c83-0000-0000-0000-602f00000000}\data\file.txt`,
                expected: `file.txt`,
            },
            {
                doc:      "subdirectory",
                base:     `C:\Projects`,
                target:   `C:\Projects\Go\main.go`,
                expected: `Go\main.go`,
            },
            {
                doc:      "same directory",
                base:     `C:\Projects`,
                target:   `C:\Projects`,
                expected: `.`,
            },
            {
                doc:      "parent directory",
                base:     `C:\Projects\Go`,
                target:   `C:\Projects`,
                expected: `..`,
            },
        }

        for _, tc := range testCases {
            t.Run(tc.doc, func(t *testing.T) {
                actual, err := remotecontext.Rel(tc.base, tc.target)
                if err != nil {
                    t.Fatal(err)
                }
                if actual != tc.expected {
                    t.Errorf("expected: %q, got: %q", tc.expected, actual)
                }

                // Try with stdlib
                actual, err = filepath.Rel(tc.base, tc.target)
                if err != nil {
                    t.Fatal(err)
                }
                if actual != tc.expected {
                    t.Errorf("expected: %q, got: %q", tc.expected, actual)
                }
            })
        }
    }

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
Sebastiaan van Stijn
2025-04-18 11:01:53 +02:00
parent 01f442b84d
commit 54a556a5ef
2 changed files with 6 additions and 18 deletions

View File

@@ -251,7 +251,7 @@ func (o *copier) copyWithWildcards(origPath string) ([]copyInfo, error) {
if err != nil {
return err
}
rel, err := remotecontext.Rel(root, path)
rel, err := filepath.Rel(root, path)
if err != nil {
return err
}
@@ -309,7 +309,7 @@ func walkSource(source builder.Source, origPath string) ([]string, error) {
if err != nil {
return err
}
rel, err := remotecontext.Rel(source.Root(), path)
rel, err := filepath.Rel(source.Root(), path)
if err != nil {
return err
}

View File

@@ -4,8 +4,6 @@ import (
"encoding/hex"
"os"
"path/filepath"
"runtime"
"strings"
"github.com/docker/docker/builder"
"github.com/docker/docker/pkg/pools"
@@ -41,7 +39,7 @@ func (c *lazySource) Hash(path string) (string, error) {
return "", err
}
relPath, err := Rel(c.root, fullPath)
relPath, err := filepath.Rel(c.root, fullPath)
if err != nil {
return "", errors.WithStack(convertPathError(err, cleanPath))
}
@@ -85,19 +83,9 @@ func (c *lazySource) prepareHash(relPath string, fi os.FileInfo) (string, error)
return sum, nil
}
// Rel makes a path relative to base path. Same as `filepath.Rel` but can also
// handle UUID paths in windows.
// Rel is an alias for [filepath.Rel].
//
// Deprecated: use [filepath.Rel] instead; this function is no longer used and will be removed in the next release.
func Rel(basepath string, targpath string) (string, error) {
// filepath.Rel can't handle UUID paths in windows
if runtime.GOOS == "windows" {
pfx := basepath + `\`
if strings.HasPrefix(targpath, pfx) {
p := strings.TrimPrefix(targpath, pfx)
if p == "" {
p = "."
}
return p, nil
}
}
return filepath.Rel(basepath, targpath)
}