{"id":18402695,"url":"https://github.com/jasei/pathutil-go","last_synced_at":"2026-03-09T11:03:05.329Z","repository":{"id":19810983,"uuid":"87984045","full_name":"JaSei/pathutil-go","owner":"JaSei","description":"File path utility inspired by David Golden's Path::Tiny","archived":false,"fork":false,"pushed_at":"2023-05-19T04:59:53.000Z","size":155,"stargazers_count":3,"open_issues_count":1,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-03-05T16:46:50.526Z","etag":null,"topics":["go","golang","hacktoberfest","library","path"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/JaSei.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-04-11T22:14:20.000Z","updated_at":"2022-10-10T19:48:18.000Z","dependencies_parsed_at":"2024-06-20T15:53:35.344Z","dependency_job_id":null,"html_url":"https://github.com/JaSei/pathutil-go","commit_stats":null,"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JaSei%2Fpathutil-go","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JaSei%2Fpathutil-go/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JaSei%2Fpathutil-go/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JaSei%2Fpathutil-go/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/JaSei","download_url":"https://codeload.github.com/JaSei/pathutil-go/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247612359,"owners_count":20966726,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["go","golang","hacktoberfest","library","path"],"created_at":"2024-11-06T02:43:12.229Z","updated_at":"2025-12-05T11:02:15.417Z","avatar_url":"https://github.com/JaSei.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# pathutil\n\n[![Release](https://img.shields.io/github/release/JaSei/pathutil-go.svg?style=flat-square)](https://github.com/JaSei/pathutil-go/releases/latest)\n[![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square)](LICENSE)\n![GitHub Actions](https://github.com/JaSei/pathutil-go/actions/workflows/workflow.yaml/badge.svg)\n[![Go Report Card](https://goreportcard.com/badge/github.com/JaSei/pathutil-go?style=flat-square)](https://goreportcard.com/report/github.com/JaSei/pathutil-go)\n[![GoDoc](https://godoc.org/github.com/JaSei/pathutil-go?status.svg\u0026style=flat-square)](http://godoc.org/github.com/JaSei/pathutil-go)\n[![codecov.io](https://codecov.io/github/JaSei/pathutil-go/coverage.svg?branch=master)](https://codecov.io/github/JaSei/pathutil-go?branch=master)\n[![Sourcegraph](https://sourcegraph.com/github.com/JaSei/pathutil-go/-/badge.svg)](https://sourcegraph.com/github.com/JaSei/pathutil-go?badge)\n\nPathutil is I/O utility primary inspired by David Golden's\n[Path::Tiny](https://metacpan.org/pod/Path::Tiny). It is friendlier to use than\n[path](https://golang.org/pkg/path/),\n[filepath](https://golang.org/pkg/path/filepath/) and provides many of other\nfunctions which isn't in core libraries (like `Copy` for example)\n\n### SYNOPSIS\n\n    import (\n    \t\"fmt\"\n    \t\"github.com/JaSei/pathutil-go\"\n    )\n\n    // creating pathutil objects\n    dir, _ := pathutil.New(\"/tmp\")\n    foo, _ := pathutil.New(\"foo.txt\")\n\n    subdir, _ := dir.Child(\"foo\")\n    bar, _ := subdir.Child(\"bar.txt\")\n\n    // stringifies as cleaned up path\n    file, _ := pathutil.New(\"./foo.txt\")\n    fmt.Println(file) // \"foo.txt\"\n\n    // reading files\n    guts, _ := file.Slurp()\n    lines, _ := file.Lines()\n\n    // writing files\n    bar.Spew(data)\n\n    // reading directories\n    children, _ := dir.Children()\n    for _, child := range children {\n    }\n\n\n### SEE ALSO\n\n* [Path::Tiny](https://metacpan.org/pod/Path::Tiny) for Perl\n\n* [better files](https://github.com/pathikrit/better-files) for Scala\n\n* [pathlib](https://docs.python.org/3/library/pathlib.html) for python\n\nBREAKING CHANGE 0.3.1 -\u003e 1.0.0\n\n1. `NewTempFile` or `NewTempDir` don't need TempOpt struct\n\n    //0.3.1 default\n    pathutil.NewTempFile(pathutil.TempOpt{})\n    //0.3.1 custom\n    pathutil.NewTempFile(pathutil.TempOpt{Dir: \"/test\", Prefix: \"pre\"})\n\n    //1.0.0 default\n    pathutil.NewTempFile()\n    //1.0.0 custom\n    pathutil.NewTempFile(Dir(\"/test\"), Prefix(\"pre\"))\n\n2. `New` method parameter allowed `string` type or type implements\n`fmt.Stringer` interface\n\n    //0.3.1\n    pathutil.New(otherPath.String(), \"test\")\n\n    //1.0.0\n    pathutil.New(otherPath, \"test\")\n\nThis shouldn't be breaking change, but if you use in some code variadic\nparameter as input of `pathutil.New`, then can be problem\n\n    //0.3.1\n    func(p ...string) {\n    \tpathutil.New(p...)\n    }(\"a\", \"b\")\n\n    //1.0.0\n    func(p ...string) {\n    \tn := make([]interface{}, len(p))\n    \tfor i, v := range p {\n    \t\tn[i] = v\n    \t}\n    \tpathutil.New(n...)\n    }(\"a\", \"b\")\n\n3. There is new (more handfull) crypto API\n\n    //0.3.1\n    import (\n    \t\"crypto\"\n    \t\"github.com/JaSei/pathutil-go\"\n    )\n    ...\n\n    hash, err := path.Crypto(crypto.SHA256)\n    if err == nil {\n    \tfmt.Printf(\"%s\\t%s\\n\", hash.HexSum(), path.String())\n    }\n\n    //1.0.0\n    import (\n    \t\"github.com/JaSei/pathutil-go\"\n    )\n    ...\n\n    hash, err := path.CryptoSha256()\n    if err == nil {\n    \tfmt.Printf(\"%s\\t%s\\n\", hash, path.String())\n    }\n\nThis new crypto API return [hashutil](github.com/JaSei/hashutil-go) struct which\nis more handfull for compare, transformation and next hash manipulation.\n\n## Usage\n\n#### type LinesFunc\n\n```go\ntype LinesFunc func(string)\n```\n\n\n#### type Path\n\n```go\ntype Path interface {\n\tString() string\n\tCanonpath() string\n\tBasename() string\n\n\tChdir() (Path, error)\n\tRename(string) (Path, error)\n\n\tStat() (os.FileInfo, error)\n\n\tIsDir() bool\n\tExists() bool\n\tIsFile() bool\n\tIsRegularFile() bool\n\n\tRemove() error\n\tRemoveTree() error\n\n\tVisit(VisitFunc, VisitOpt)\n\tCopyFile(string) (Path, error)\n\n\tCopyFrom(io.Reader) (int64, error)\n\n\tCryptoMd5() (hashutil.Md5, error)\n\tCryptoSha1() (hashutil.Sha1, error)\n\tCryptoSha256() (hashutil.Sha256, error)\n\tCryptoSha384() (hashutil.Sha384, error)\n\tCryptoSha512() (hashutil.Sha512, error)\n\n\tMakePath() error\n\tMakePathMode(os.FileMode) error\n\n\tOpenReader() (ReadSeekCloser, error)\n\tOpenWriter() (*os.File, error)\n\tOpenWriterAppend() (*os.File, error)\n\n\tSlurp() (string, error)\n\tSlurpBytes() ([]byte, error)\n\n\tSpew(string) error\n\tSpewBytes([]byte) error\n\n\tLines() ([]string, error)\n\tLinesWalker(LinesFunc) error\n\n\tChild(...string) (Path, error)\n\tChildren() ([]Path, error)\n\n\tParent() Path\n\n\tAppend(string) error\n\tAppendBytes([]byte) error\n}\n```\n\n\n#### func  Cwd\n\n```go\nfunc Cwd(subpath ...string) (Path, error)\n```\nCwd create new Path from current working directory optional is possible to set\nsubpath\n\nfor example\n\n    gitConfigPath, err := pathutil.Cwd('.git/config')\n\n#### func  Home\n\n```go\nfunc Home(subpath ...string) (Path, error)\n```\nHome create new Path from home directory optional is possible to set subpath\n\nfor example\n\n    initPath, err := pathutil.Home('.config/nvim/init.vim')\n\n(internally use https://github.com/mitchellh/go-homedir library)\n\n#### func  New\n\n```go\nfunc New(path ...interface{}) (Path, error)\n```\nNew construct Path\n\nfor example\n\n    path := New(\"/home/test\", \".vimrc\")\n\ninput can be `string` or type implements `fmt.Stringer` interface\n\n#### func  NewTempDir\n\n```go\nfunc NewTempDir(options ...TempOpt) (Path, error)\n```\nNewTempDir create temp directory\n\nfor cleanup use `defer`\n\n    \ttempdir, err := pathutil.NewTempDir()\n     defer tempdir.RemoveTree()\n\nif you need set directory or prefix, then use `TempDir` and/or `TempPrefix`\n\n    temp, err := NewTempFile(TempDir(\"/home/my/test\"), TempPrefix(\"myfile\"))\n    ...\n\n#### func  NewTempFile\n\n```go\nfunc NewTempFile(options ...TempOpt) (p Path, err error)\n```\nNewTempFile create temp file\n\nfor cleanup use defer\n\n    temp, err := NewTempFile(TempOpt{})\n    defer temp.Remove()\n\nif you need only temp file name, you must delete file\n\n    temp, err := NewTempFile()\n    temp.Remove()\n\nif you need set directory or prefix, then use `TempDir` and/or `TempPrefix`\n\n    temp, err := NewTempFile(TempDir(\"/home/my/test\"), TempPrefix(\"myfile\"))\n    ...\n\n#### type PathImpl\n\n```go\ntype PathImpl struct {\n}\n```\n\ntype PathImpl implements Path interface\n\n#### func (PathImpl) Append\n\n```go\nfunc (path PathImpl) Append(data string) error\n```\n\n#### func (PathImpl) AppendBytes\n\n```go\nfunc (path PathImpl) AppendBytes(data []byte) (err error)\n```\n\n#### func (PathImpl) Basename\n\n```go\nfunc (path PathImpl) Basename() string\n```\nBasename like path/filepath.Base\n\n#### func (PathImpl) Canonpath\n\n```go\nfunc (path PathImpl) Canonpath() string\n```\nCanonpath retrun path with right os separator\n\n#### func (PathImpl) Chdir\n\n```go\nfunc (path PathImpl) Chdir() (Path, error)\n```\nChdir change current working directory do the path and return old current\nworking directory\n\n#### func (PathImpl) Child\n\n```go\nfunc (path PathImpl) Child(childName ...string) (Path, error)\n```\n\n#### func (PathImpl) Children\n\n```go\nfunc (path PathImpl) Children() ([]Path, error)\n```\n\n#### func (PathImpl) CopyFile\n\n```go\nfunc (srcPath PathImpl) CopyFile(dst string) (p Path, err error)\n```\n\n#### func (PathImpl) CopyFrom\n\n```go\nfunc (path PathImpl) CopyFrom(reader io.Reader) (copyied int64, err error)\n```\nCopyFrom copy stream from reader to path (file after copy close and sync)\n\n#### func (PathImpl) CryptoMd5\n\n```go\nfunc (path PathImpl) CryptoMd5() (hashutil.Md5, error)\n```\nCryptoMd5 method access hash funcionality like Path::Tiny Digest return\n[hashutil.Md5](github.com/JaSei/hashutil-go) type\n\nfor example print of Md5 hexstring\n\n    hash, err := path.CryptoMd5()\n    fmt.Println(hash)\n\n#### func (PathImpl) CryptoSha1\n\n```go\nfunc (path PathImpl) CryptoSha1() (hashutil.Sha1, error)\n```\nCryptoSha1 method access hash funcionality like Path::Tiny Digest return\n[hashutil.Sha1](github.com/JaSei/hashutil-go) type\n\nfor example print of Sha1 hexstring\n\n    hash, err := path.CryptoSha1()\n    fmt.Println(hash)\n\n#### func (PathImpl) CryptoSha256\n\n```go\nfunc (path PathImpl) CryptoSha256() (hashutil.Sha256, error)\n```\nCryptoSha256 method access hash funcionality like Path::Tiny Digest return\n[hashutil.Sha256](github.com/JaSei/hashutil-go) type\n\nfor example print of Sha256 hexstring\n\n    hash, err := path.CryptoSha256()\n    fmt.Println(hash)\n\n#### func (PathImpl) CryptoSha384\n\n```go\nfunc (path PathImpl) CryptoSha384() (hashutil.Sha384, error)\n```\nCryptoSha384 method access hash funcionality like Path::Tiny Digest return\n[hashutil.Sha384](github.com/JaSei/hashutil-go) type\n\nfor example print of Sha284 hexstring\n\n    hash, err := path.CryptoSha284()\n    fmt.Println(hash)\n\n#### func (PathImpl) CryptoSha512\n\n```go\nfunc (path PathImpl) CryptoSha512() (hashutil.Sha512, error)\n```\nCryptoSha512 method access hash funcionality like Path::Tiny Digest return\n[hashutil.Sha512](github.com/JaSei/hashutil-go) type\n\nfor example print of Sha512 hexstring\n\n    hash, err := path.CryptoSha512()\n    fmt.Println(hash)\n\n#### func (PathImpl) Exists\n\n```go\nfunc (path PathImpl) Exists() bool\n```\n\n#### func (PathImpl) IsDir\n\n```go\nfunc (path PathImpl) IsDir() bool\n```\nIsDir return true if path is dir\n\n#### func (PathImpl) IsFile\n\n```go\nfunc (path PathImpl) IsFile() bool\n```\nIsFile return true is path exists and not dir (symlinks, devs, regular files)\n\n#### func (PathImpl) IsRegularFile\n\n```go\nfunc (path PathImpl) IsRegularFile() bool\n```\nIsRegularFile return true if path is regular file (wihtout devs, symlinks, ...)\n\n#### func (PathImpl) Lines\n\n```go\nfunc (path PathImpl) Lines() ([]string, error)\n```\nRead all lines and return as array of lines\n\n#### func (PathImpl) LinesWalker\n\n```go\nfunc (path PathImpl) LinesWalker(linesFunc LinesFunc) (err error)\n```\nLinesWalker read lines in file and call LinesFunc with line parameter\n\nfor example:\n\n    lines := make([]string, 0)\n\n    linesFuncError := path.LinesWalker(func(line string) {\n    \tlines = append(lines, line)\n    })\n\n#### func (PathImpl) MakePath\n\n```go\nfunc (path PathImpl) MakePath() error\n```\nMake path create directory(ies) in path if not exists (like `mkdir -p`) with\ndefault 0777 mode if you need set mode, use `MakePathMode`\n\n#### func (PathImpl) MakePathMode\n\n```go\nfunc (path PathImpl) MakePathMode(mode os.FileMode) error\n```\nMake path create directory(ies) in path if not exists (like `mkdir -p`) with\ndefault given mode\n\n#### func (PathImpl) OpenReader\n\n```go\nfunc (path PathImpl) OpenReader() (ReadSeekCloser, error)\n```\nOpenReader retun ReadSeekCloser interface\n\nfor example:\n\n    path, _ := New(\"/bla/bla\")\n    r, err := path.OpenReader()\n    if err != nil {\n    \tpanic(err)\n    }\n    defer r.Close()\n\n#### func (PathImpl) OpenWriter\n\n```go\nfunc (path PathImpl) OpenWriter() (*os.File, error)\n```\nOpenWriter retun *os.File as new file (like `\u003e\u003e`)\n\nfor example:\n\n    \tpath, _ := NewFilePath(FilePathOpt{})\n    \tfile, err := path.OpenWriter()\n    \tif err != nil {\n    \t\tpanic(err)\n    \t}\n    \tdefer func(){\n    \t\tfile.Close()\n    \t\tfile.Sync()\n    \t}()\n\n     writer.Write(some_bytes)\n\n#### func (PathImpl) OpenWriterAppend\n\n```go\nfunc (path PathImpl) OpenWriterAppend() (*os.File, error)\n```\nOpenWriterAppend create new writer, similar as `OpenWriter` but append (like\n`\u003e`)\n\n#### func (PathImpl) Parent\n\n```go\nfunc (path PathImpl) Parent() Path\n```\n\n    \tpath,_ := New(\"foo/bar/baz\"); parent := path.Parent()   // foo/bar\n     path,_ := New(\"foo/wible.txt\"); parent := path.Parent() // foo\nReturns a `Path` of corresponding to the parent directory of the original\ndirectory or file\n\n#### func (PathImpl) Remove\n\n```go\nfunc (path PathImpl) Remove() error\n```\nRemove file\n\n    err := path.Remove()\n\nlike os.Remove\n\n#### func (PathImpl) RemoveTree\n\n```go\nfunc (path PathImpl) RemoveTree() error\n```\nRemove tree of directory(ies) include files\n\n    err := path.RemoveTree\n\nlike os.RemoveAll\n\n#### func (PathImpl) Rename\n\n```go\nfunc (old PathImpl) Rename(new string) (Path, error)\n```\nRename path to new path\n\n#### func (PathImpl) Slurp\n\n```go\nfunc (path PathImpl) Slurp() (string, error)\n```\nSlurp read the whole file and return content as string\n\n#### func (PathImpl) SlurpBytes\n\n```go\nfunc (path PathImpl) SlurpBytes() ([]byte, error)\n```\nSlurpBytes reads the whole file and return content slice of bytes like\nos.ReadFile\n\n#### func (PathImpl) Spew\n\n```go\nfunc (path PathImpl) Spew(content string) (err error)\n```\nSpew write string to file\n\n#### func (PathImpl) SpewBytes\n\n```go\nfunc (path PathImpl) SpewBytes(bytes []byte) (err error)\n```\nSpewBytes write bytes to file\n\n#### func (PathImpl) Stat\n\n```go\nfunc (path PathImpl) Stat() (os.FileInfo, error)\n```\nStat return os.FileInfo\n\n#### func (PathImpl) String\n\n```go\nfunc (path PathImpl) String() string\n```\nString return stable string representation of path this representation is linux\nlike (slash as separator) for os specific string use Canonpath method\n\n#### func (PathImpl) Visit\n\n```go\nfunc (path PathImpl) Visit(visitFunc VisitFunc, visitOpt VisitOpt)\n```\n\n#### type ReadSeekCloser\n\n```go\ntype ReadSeekCloser interface {\n\tio.Reader\n\tio.Seeker\n\tio.Closer\n}\n```\n\n\n#### type TempOpt\n\n```go\ntype TempOpt func(*tempOpt)\n```\n\nTempOpt is func for configure tempdir or tempfile\n\n#### func  TempDir\n\n```go\nfunc TempDir(dir string) TempOpt\n```\nTempDir set directory where is temp file/dir create, empty string `\"\"` (default)\nmeans TEMPDIR (`os.TempDir`)\n\n#### func  TempPrefix\n\n```go\nfunc TempPrefix(prefix string) TempOpt\n```\nTempPrefix set name beginning with prefix\n\n#### type VisitFunc\n\n```go\ntype VisitFunc func(path Path)\n```\n\n\n#### type VisitOpt\n\n```go\ntype VisitOpt struct {\n\tRecurse bool\n}\n```\n\n\n## Contributing\n\nContributions are very much welcome.\n\n### Makefile\n\nMakefile provides several handy rules, like README.md `generator` , `setup` for prepare build/dev environment, `test`, `cover`, etc...\n\nTry `make help` for more information.\n\n### Before pull request\n\nplease try:\n* run tests (`make test`)\n* run linter (`make lint`)\n* if your IDE don't automaticaly do `go fmt`, run `go fmt` (`make fmt`)\n\n### README\n\nREADME.md are generate from template [.godocdown.tmpl](.godocdown.tmpl) and code documentation via [godocdown](https://github.com/robertkrimen/godocdown).\n\nNever edit README.md direct, because your change will be lost.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjasei%2Fpathutil-go","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjasei%2Fpathutil-go","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjasei%2Fpathutil-go/lists"}