Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parsing error due to incorrect slashes with embed on windows. #75

Closed
sedyh opened this issue May 15, 2023 · 4 comments
Closed

Parsing error due to incorrect slashes with embed on windows. #75

sedyh opened this issue May 15, 2023 · 4 comments

Comments

@sedyh
Copy link

sedyh commented May 15, 2023

Problem

Hello, I found a problem in the operation of one of the UnmarshalXML in Map.
This code will cause os.ErrNotExist on windows for data/world/surface-tileset.tmx even if the file is there:

//go:embed data
var fs embed.FS
...
// File surface.tmx has reference to surface-tileset.tmx in it.
tiled.LoadFile("data/world/surface.tmx", tiled.WithFileSystem(fs))

The library allows you to insert your own fs implementation to upload files:
https://github.com/lafriks/go-tiled/blob/main/tiled.go#L76

In the process, it loads additional files (for example, tileset) for which it builds a path as follows:
https://github.com/lafriks/go-tiled/blob/main/tmx_map.go#L173

Which will return the path with windows-like slashes data\world\surface-tileset.tmx. This path will not work with embed:
golang/go#44305

Despite the fact that these are details of the implementation of a specific fs, it is part of the standard library.
So it makes sense to take these details into account inside the lib.

Solution A

Add a wrapper that converts paths in special cases.

func WithFileSystem(fileSystem fs.FS) LoaderOption {
	return func(l *loader) {
		l.FileSystem = fileSystem
		if _, ok := l.FileSystem.(*embed.FS); ok {
			l.FileSystem = WithPathRelative(FileSystem)
		}
	}
}

type PathRelativeFS struct {
	fs fs.FS
}

func WithPathRelative(fs fs.FS) fs.FS {
	return &PathRelativeFS{fs}
}

func (p *PathRelativeFS) Open(name string) (fs.File, error) {
	name = strings.Replace(name, string(filepath.Separator), "/", -1)
	return p.fs.Open(name)
}

Solution B

Add the option to use path.Join instead of filepath.Join for special occasions.

func (m *Map) GetFileFullPath(fileName string) string {
	if _, ok := m.loader.FileSystem.(*embed.FS); ok {
		return path.Join(m.baseDir, fileName)
	}
	return filepath.Join(m.baseDir, fileName)
}

Looks like it the same as #63.

@lafriks
Copy link
Owner

lafriks commented May 16, 2023

Looks like duplicate for #63 closing this.

There is also provided better solution for this: tslocum@2d2dec4

imho it is not correct to use path.Join

@lafriks lafriks closed this as completed May 16, 2023
@lafriks
Copy link
Owner

lafriks commented May 16, 2023

feel free to send PR for this

@sedyh
Copy link
Author

sedyh commented May 16, 2023

Thats strange... no one has made a fix for the issue since last year. I'l try, if I have time.

@lafriks
Copy link
Owner

lafriks commented May 17, 2023

I have no windows to test on, so I not really want to implement something I'm not able to even test :]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants