Skip to content

Latest commit

 

History

History
106 lines (76 loc) · 5.46 KB

README.md

File metadata and controls

106 lines (76 loc) · 5.46 KB
Artwork for go-pathlib.

go-pathlib

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.

Getting started 🚀

go get github.com/jeftadlvw/go-pathlib@latest
package main

import (
	"fmt"
	"github.com/jeftadlvw/go-pathlib"
)

func main() {
	p := pathlib.NewPath("path/to/your/destination")
	fmt.Println(p)
}

Features ✨

  • represent file paths as an own struct type with minimal memory overhead
  • many functions for handling file paths
  • implements encoder.TextMarshaler and encoder.TextUnmashaler, enabling automatic integration into first- and third-party parsing libraries (for e.g. text or JSON)

API Documentation 📝

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.

Roadmap 📋

Although the core API exists, I'd like to test the look and feel of this library in some other projects before committing to a major release.

🔖Current version: 0.0.2

The following features are planned and fixed on the roadmap. They extend the API and improve the integration into other ecosystems. Because go-pathlib should stay a single-file library, new features are categorized into optional extensions.

0.0.3

  • integration into go-validator (custom field types and validators)

0.0.4

  • filesystem operations (create, move, delete or rename files and directories)
  • APIs for temporary files and directories
  • abstractions: read/write to files, get path stats

0.0.5

  • filesystem case sensitivity: compare paths on filesystem level, check if path is case-sensitive

Future

  • recursive globbing using double asterisks (stable and tested without using external dependencies)
  • extend globbing to not include directories
  • implement "range over function" for globbing
  • function to check if a file is hidden
  • tested Windows support

This is a non-exhaustive list. Feel free to suggest other features and integrations!

Recommendations 🌚

Persisting file paths

When persisting file paths in e.g. configuration files or a database, 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 a configuration file, enclose the path with e.g. quotation marks: "path/to/foo.bar".

Path equality and case sensitivity

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 several functions to check for path equality:

  • Equals: default, lexical, case-sensitive
  • EqualsFlat: lexical, case-insensitive
  • EqualsFs (unimplemented): filesystem equality

Gotcha's ‼️

On Unix-based operating systems, Windows path roots (e.g. C:\ or D:\) are not considered as filepath roots. Instead, they are seen as relative path elements. With this in mind, Path.Root() might still "correctly" return e.g. C: for C:/foo.bar on Unix-based operating systems.

This is also it's recommended to persist relative paths, as you won't fall into these types of implementation detail traps.

Contributing 👥

Feel free to open issues and merge requests. Any help or feedback is highly appreciated!

Attributions 🖊️

This project makes use of the following third-party dependencies. Their licenses can be found at third_party.

  1. testify @ https://github.com/stretchr/testify

    • License: MIT License
    • Copyright (c) 2012-2020 Mat Ryer, Tyler Bunnell and contributors.
  2. gomarkdoc @ https://github.com/princjef/gomarkdoc

    • License: MIT License
    • Copyright (c) 2019 Jeff Principe

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.