Embed: relative paths to parent directories

Hi there,
my question is: is it possible to enable relative paths for go:embed?
example: I’d like to include my README.md file to the project, but I put all my embeded variables in assets package.
code:
//go:embed …/README.md
var README []byte

problem:
assets/assets.go:7:12: pattern …/README.md: invalid pattern syntax

Have you tried using a valid path with only 2 dots?

I never used go:embed though all examples I can find about it do use relative pathes (though none of the examples advanced to a parent, all went down to child folders).

Have you tried using a valid path with only 2 dots?

yah, just typo in here.

also, the paths to sub-folders works fine. The problem is with path to parent directory.

now, I can see, that my error comes from io/fs.ValidPath usage in golang source code go/src/cmd/go/internal/load/pkg.go (line 1971):

func ValidPath 1.16

func ValidPath(name string) bool

ValidPath reports whether the given path name is valid for use in a call to Open.

Path names passed to open are UTF-8-encoded, unrooted, slash-separated sequences of path elements, like “x/y/z”. Path names must not contain an element that is “.” or “..” or the empty string, except for the special case that the root directory is named “.”. Paths must not start or end with a slash: “/x” and “x/” are invalid.

Note that paths are slash-separated on all systems, even Windows. Paths containing other characters such as backslash and colon are accepted as valid, but those characters must never be interpreted by an FS implementation as path element separators.

elements, like “x/y/z”. Path names must not contain an element that is “.” or “…” or the empty string,

however, I don’t understand why it is not allowed, because os.Open allows strings with “.” and “…” :confused:

I read this as if ./../README.md could work.

I read this as if ./../README.md could work.

it couldn’t work because of io/fs.ValidPath method, which is used in golang source code

Path names must not contain an element that is “.” or “..” or the empty string, except for the special case that the root directory is named “.”. Paths must not start or end with a slash: “/x” and “x/” are invalid.
1 Like

"except for the special case where the root is ."

Though I just checked, and it seems to be indeed not accepted for whatever reason… A path like that is accepted by Windows, Linux and probably Mac as well.

queting source code of io/fs:
special case when name is “.” is checked her:

        if name == "." {
                // special case
                return true
        }

otherwise, if this condition isn’t checked:

        // Iterate over elements in name, checking each.
        for {
                i := 0
                for i < len(name) && name[i] != '/' {
                        i++
                }
                elem := name[:i]
                if elem == "" || elem == "." || elem == ".." {
                        return false
                }
                if i == len(name) {
                        return true // reached clean ending
                }
                name = name[i+1:]
        }

so I suppose, that this bug is caused by this io/fs.ValidPath call:

                // Check pattern is valid for //go:embed.
                if _, err := path.Match(pattern, ""); err != nil || !validEmbedPattern(pattern) {
                        return nil, nil, fmt.Errorf("invalid pattern syntax")
                }
func validEmbedPattern(pattern string) bool {
        return pattern != "." && fs.ValidPath(pattern)
}

Any updates on this topic ?

I opened an issue in golang repo. I think, that we should discuss about this idea on here. for exemple, if the .. is in a module area, go:embed could be allowed? what do you guys think about it?