{"id":13832064,"url":"https://github.com/twpayne/go-vfs","last_synced_at":"2025-04-05T06:07:43.710Z","repository":{"id":47705391,"uuid":"159222419","full_name":"twpayne/go-vfs","owner":"twpayne","description":"Package vfs provides an abstraction of the os and io packages that is easy to test.","archived":false,"fork":false,"pushed_at":"2024-03-31T16:30:47.000Z","size":194,"stargazers_count":82,"open_issues_count":0,"forks_count":6,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-04-02T00:34:49.024Z","etag":null,"topics":["filesystem","fs","go","golang","test","testing"],"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/twpayne.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":"2018-11-26T19:35:20.000Z","updated_at":"2025-03-15T23:34:26.000Z","dependencies_parsed_at":"2024-01-15T15:46:09.447Z","dependency_job_id":"edf41248-01cc-46e1-826e-a00d10689e42","html_url":"https://github.com/twpayne/go-vfs","commit_stats":null,"previous_names":[],"tags_count":43,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/twpayne%2Fgo-vfs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/twpayne%2Fgo-vfs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/twpayne%2Fgo-vfs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/twpayne%2Fgo-vfs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/twpayne","download_url":"https://codeload.github.com/twpayne/go-vfs/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247294538,"owners_count":20915340,"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":["filesystem","fs","go","golang","test","testing"],"created_at":"2024-08-04T10:01:49.721Z","updated_at":"2025-04-05T06:07:43.693Z","avatar_url":"https://github.com/twpayne.png","language":"Go","funding_links":[],"categories":["Go"],"sub_categories":[],"readme":"# go-vfs\n\n[![PkgGoDev](https://pkg.go.dev/badge/github.com/twpayne/go-vfs/v5)](https://pkg.go.dev/github.com/twpayne/go-vfs/v5)\n\nPackage `vfs` provides an abstraction of the `os` and `io` packages that is easy\nto test.\n\n## Key features\n\n* File system abstraction layer for commonly-used `os` and `io` functions from\n  the standard library.\n\n* Powerful and easy-to-use declarative testing framework, `vfst`. You declare\n  the desired state of the filesystem after your code has run, and `vfst` tests\n  that the filesystem matches that state. For a quick tour of `vfst`'s features,\n  see [the examples in the\n  documentation](https://godoc.org/github.com/twpayne/go-vfs/v5/vfst#pkg-examples).\n\n* Compatibility with\n  [`github.com/spf13/afero`](https://github.com/spf13/afero) and\n  [`github.com/src-d/go-billy`](https://github.com/src-d/go-billy).\n\n## Quick start\n\n`vfs` provides implementations of the `FS` interface:\n\n```go\n// An FS is an abstraction over commonly-used functions in the os and io\n// packages.\ntype FS interface {\n    Chmod(name string, mode fs.FileMode) error\n    Chown(name string, uid, git int) error\n    Chtimes(name string, atime, mtime time.Time) error\n    Create(name string) (*os.File, error)\n    Glob(pattern string) ([]string, error)\n    Lchown(name string, uid, git int) error\n    Link(oldname, newname string) error\n    Lstat(name string) (fs.FileInfo, error)\n    Mkdir(name string, perm fs.FileMode) error\n    Open(name string) (fs.File, error)\n    OpenFile(name string, flag int, perm fs.FileMode) (*os.File, error)\n    PathSeparator() rune\n    RawPath(name string) (string, error)\n    ReadDir(dirname string) ([]fs.DirEntry, error)\n    ReadFile(filename string) ([]byte, error)\n    Readlink(name string) (string, error)\n    Remove(name string) error\n    RemoveAll(name string) error\n    Rename(oldpath, newpath string) error\n    Stat(name string) (fs.FileInfo, error)\n    Symlink(oldname, newname string) error\n    Truncate(name string, size int64) error\n    WriteFile(filename string, data []byte, perm fs.FileMode) error\n}\n```\n\nTo use `vfs`, you write your code to use the `FS` interface, and then use\n`vfst` to test it.\n\n`vfs` also provides functions `MkdirAll` (equivalent to `os.MkdirAll`),\n`Contains` (an improved `filepath.HasPrefix`), and `Walk` (equivalent to\n`filepath.Walk`) that operate on an `FS`.\n\nThe implementations of `FS` provided are:\n\n* `OSFS` which calls the underlying `os` and `io` functions directly.\n\n* `PathFS` which transforms all paths to provide a poor-man's `chroot`.\n\n* `ReadOnlyFS` which prevents modification of the underlying FS.\n\n* `TestFS` which assists running tests on a real filesystem but in a temporary\n  directory that is easily cleaned up. It uses `OSFS` under the hood.\n\nExample usage:\n\n```go\n// writeConfigFile is the function we're going to test. It can make arbitrary\n// changes to the filesystem through fileSystem.\nfunc writeConfigFile(fileSystem vfs.FS) error {\n    return fileSystem.WriteFile(\"/home/user/app.conf\", []byte(`app config`), 0644)\n}\n\n// TestWriteConfigFile is our test function.\nfunc TestWriteConfigFile(t *testing.T) {\n    // Create and populate an temporary directory with a home directory.\n    fileSystem, cleanup, err := vfst.NewTestFS(map[string]any{\n        \"/home/user/.bashrc\": \"# contents of user's .bashrc\\n\",\n    })\n\n    // Check that the directory was populated successfully.\n    if err != nil {\n        t.Fatalf(\"vfsTest.NewTestFS(_) == _, _, %v, want _, _, \u003cnil\u003e\", err)\n    }\n\n    // Ensure that the temporary directory is removed.\n    defer cleanup()\n\n    // Call the function we want to test.\n    if err := writeConfigFile(fileSystem); err != nil {\n        t.Error(err)\n    }\n\n    // Check properties of the filesystem after our function has modified it.\n    vfst.RunTests(t, fileSystem, \"app_conf\",\n        vfst.TestPath(\"/home/user/app.conf\",\n            vfst.TestModeIsRegular(),\n            vfst.TestModePerm(0644),\n            vfst.TestContentsString(\"app config\"),\n        ),\n    )\n}\n```\n\n## `github.com/spf13/afero` compatibility\n\nThere is a compatibility shim for\n[`github.com/spf13/afero`](https://github.com/spf13/afero) in\n[`github.com/twpayne/go-vfsafero`](https://github.com/twpayne/go-vfsafero). This\nallows you to use `vfst` to test existing code that uses\n[`afero.FS`](https://godoc.org/github.com/spf13/afero#Fs). See [the\ndocumentation](https://godoc.org/github.com/twpayne/go-vfsafero) for an example.\n\n## `github.com/src-d/go-billy` compatibility\n\nThere is a compatibility shim for\n[`github.com/src-d/go-billy`](https://github.com/src-d/go-billy) in\n[`github.com/twpayne/go-vfsbilly`](https://github.com/twpayne/go-vfsbilly). This\nallows you to use `vfst` to test existing code that uses\n[`billy.Filesystem`](https://godoc.org/github.com/src-d/go-billy#Filesystem).\nSee [the documentation](https://godoc.org/github.com/twpayne/go-vfsbilly) for an\nexample.\n\n## Motivation\n\n`vfs` was inspired by\n[`github.com/spf13/afero`](https://github.com/spf13/afero). So, why not use\n`afero`?\n\n* `afero` has several critical bugs in its in-memory mock filesystem\n  implementation `MemMapFs`, to the point that it is unusable for non-trivial\n  test cases. `vfs` does not attempt to implement an in-memory mock filesystem,\n  and instead only provides a thin layer around the standard library's `os` and\n  `io` packages, and as such should have fewer bugs.\n\n* `afero` does not support creating or reading symbolic links, and its\n  `LstatIfPossible` interface is clumsy to use as it is not part of the\n  `afero.Fs` interface. `vfs` provides out-of-the-box support for symbolic links\n  with all methods in the `FS` interface.\n\n* `afero` has been effectively abandoned by its author, and a \"friendly fork\"\n  ([`github.com/absfs/afero`](https://github.com/absfs/afero)) has not seen much\n  activity. `vfs`, by providing much less functionality than `afero`, should be\n  smaller and easier to maintain.\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftwpayne%2Fgo-vfs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftwpayne%2Fgo-vfs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftwpayne%2Fgo-vfs/lists"}