A simple one-file library for handling filesystem paths. Utilizing Golang's path/filepath, inspired by Python's pathlib API. It abstracts the standard library by providing a simple immutable struct that acts as a source of truth for file paths.
This library is developed and tested on Unix-based operating systems. Windows should work (in theory), please open an issue if you face any problems.
Minimum tested Go version: 1.22
Current State: stabilizing API, tested across multiple platforms (Linux, macOS and Windows), API scope is not expected to be reduced. More see Roadmap.
go get github.com/jeftadlvw/go-pathlib@latestpackage main
import (
"fmt"
"github.com/jeftadlvw/go-pathlib/pathlib"
)
func main() {
p := pathlib.NewPath("path/to/your/destination")
fmt.Println(p)
}- represent file paths as an own struct type with minimal memory overhead
- many functions for handling file paths
- implements
encoder.TextMarshalerandencoder.TextUnmashaler, enabling automatic integration into first- and third-party parsing libraries (for e.g. text or JSON)
Repository-local documentation can be found at docs/go-pathlib.md. It's auto-generated by gomarkdoc using the docstrings in the source code.
The file is updated regularly and gives a good general overview on the API. Up-to-date documentation can be found in the source code.
🔖 Current version: 0.0.4
The API stabilized and is covered by many test cases. Tests are run on Linux, macOS and Windows. The current API scope is not expected to be modified or reduced. The only thing the library needs now is real-world usage in projects to catch missed cross-platform errors and refine the look-and-feel of the APIs. When the library has been tested and evaluated in other projects over a longer time, a v1 release is more likely.
Next features are planned and fixed on the roadmap for the next release(s). They extend and improve API semantics and internals and make the library more mature. Future features are planned, but not focussed on being implemented next per sé. They might, but are not prioritized.
Next
- doublestar (
**) glob pattern matching using https://github.com/bmatcuk/doublestar
Future
- parallelize recursive filesystem walking and globbing
- implement "range over function" for globbing (requires newer go versions)
Planned extensions
- integration into go-validator (custom field types and validators)
This is a non-exhaustive list. Feel free to suggest other features and integrations!
Internally, all paths are stored in a canonical Posix form (forward slashes, Windows anchors separated out). This keeps the core logic simple and platform-independent.
Constructors:
NewPath()is the safe default. It detects the current platform and handles Windows volume names and UNC roots automatically by branching to eitherNewPathFromPosix()orNewPathFromWindows(). Use it for path strings from any source, including OS APIs (e.g.os.Getwd(),filepath.EvalSymlinks()).NewPathFromPosix()assumes a Posix path and performs no Windows anchor parsing.NewPathFromWindows()always applies separator replacement (\\→/) and Windows anchor parsing regardless of the platform. If no Windows anchor is detected, paths behave like regular canonical posix paths.
Output follows the principle of platform-native by default, explicit when needed:
String()returns the platform-native representation (backslashes on Windows, forward slashes on Posix) by branching to eitherToPosix()orToWindows(). This is what you pass to OS APIs likeos.Open().ToPosix()always returns forward slashes. Use this for serialization and cross-platform storage. Windows anchors are included (including the double slash for UNC paths), but formatted as forward slashes.ToWindows()always returns backslashes. Use this when generating Windows paths on any platform.
Methods that return path components (Anchor(), Base(), Parts(), Split(), etc.) follow the same platform-native convention where separators are visible (e.g. Anchor() returns \\host\share on Windows, //host/share on Posix).
Backslashes (\) are allowed in regular Posix path part names, but are seen as path separators in Windows paths. Thus, a path string containing a backslash is interpreted differently on different operating systems. This is a problem if a filepath with backslashes is persisted using Posix and read/used on Windows.
There is really nothing to prevent this behavior, which is why this library prints a warning to stderr if a Posix path string contains a backslash. You can disable these warnings by setting pathlib.PrintBackslashWarningOnPosix to false.
When persisting file paths in e.g. configuration files or a database, use lowercase paths and use the posix representation for maximum portability. Also persist a path relative to some base path, and resolve the absolute path at runtime.
Enforce that the start and end of a path are clearly defined to escape whitespace usage. If you store paths in a database, then the path is naturally constrained by the database field. But when persisted in e.g. a configuration file, enclose the path with e.g. quotation marks: "path/to/foo.bar".
Don't assume the underlying filesystem is case-insensitive. This is the case for Windows and MacOS, but not for e.g. Linux.
Whether you design the paths in your application to be case-sensitive or not is your decision. But keep in mind that case sensitivity also comes with path ambiguity (e.g.: should file.txt and FILE.txt be treated equally?).
Although we recommend handling paths in a case-insensitive manner, we respect stricter designs and follow the principle of being strict by default, while allowing flexibility explicitly. We provide functions to check for path equality:
Equals: default, lexical, case-sensitive by default, but switchable with flagEqualsString: convenience wrapper forEquals, where the argument is interpreted as a canonical Posix string. Reserve it for strings you control, such asToPosix()output or serialized config, not OS-native strings likeString(). For those, parse first:p.Equals(NewPath(s)).EqualsFs: filesystem equality (only inpathlib_fs.go)
Feel free to open issues and pull requests. Any help or feedback is highly appreciated!
See NOTICE.md for a complete list of used third party projects and source code.
The displayed Gopher in the artwork is licensed under the Creative Commons 4.0 Attribution License as per https://go.dev/brand#logo (last seen: 30-09-2024). This project's artwork falls under the same licence.