mirror of https://github.com/spf13/afero.git
reorganize and update readme
This commit is contained in:
parent
4d968e2d2e
commit
f85f3b3779
228
README.md
228
README.md
|
@ -4,71 +4,49 @@ A FileSystem Abstraction System for Go
|
||||||
|
|
||||||
[![Build Status](https://travis-ci.org/spf13/afero.svg)](https://travis-ci.org/spf13/afero) [![GoDoc](https://godoc.org/github.com/spf13/afero?status.svg)](https://godoc.org/github.com/spf13/afero)
|
[![Build Status](https://travis-ci.org/spf13/afero.svg)](https://travis-ci.org/spf13/afero) [![GoDoc](https://godoc.org/github.com/spf13/afero?status.svg)](https://godoc.org/github.com/spf13/afero)
|
||||||
|
|
||||||
## Overview
|
# Overview
|
||||||
|
|
||||||
Package Afero provides types and methods for interacting with the filesystem,
|
Afero is an filesystem framework providing a simple, uniform and universal API
|
||||||
as an abstraction layer.
|
interacting with any filesystem, as an abstraction layer providing interfaces,
|
||||||
|
types and methods. Afero has an exceptionally clean interface and simple design
|
||||||
|
without needless constructors or initialization methods.
|
||||||
|
|
||||||
It provides a few implementations that are largely interoperable. One that
|
Afero is also a library providing a base set of interoperable backend
|
||||||
uses the operating system filesystem, one that uses memory to store files
|
filesystems that make it easy to work with afero while retaining all the power
|
||||||
(cross platform) and an interface that should be implemented if you want to
|
and benefit of the os and ioutil packages.
|
||||||
provide your own filesystem.
|
|
||||||
|
|
||||||
It is suitable for use in a any situation where you would consider using
|
Afero provides significant improvements over using the os package alone, most
|
||||||
the OS package as it provides an additional abstraction that makes it
|
notably the ability to create mock and testing filesystems without relying on the disk.
|
||||||
easy to use a memory backed file system during testing. It also adds
|
|
||||||
support for the http filesystem for full interoperability.
|
|
||||||
|
|
||||||
Afero has an exceptionally clean interface and simple design without needless
|
It is suitable for use in a any situation where you would consider using the OS
|
||||||
constructors or initialization methods.
|
package as it provides an additional abstraction that makes it easy to use a
|
||||||
|
memory backed file system during testing. It also adds support for the http
|
||||||
## The name
|
filesystem for full interoperability.
|
||||||
|
|
||||||
Initially this project was called fs. Unfortunately as I used it, the
|
|
||||||
name proved confusing, there were too many fs’. In looking for
|
|
||||||
alternatives I looked up the word 'abstract' in a variety of different
|
|
||||||
languages. Afero is the Greek word for abstract and it seemed to be a
|
|
||||||
fitting name for the project. It also means ‘to do’ or ‘thing’ in
|
|
||||||
Esperanto which is also fitting.
|
|
||||||
|
|
||||||
## Interface
|
|
||||||
|
|
||||||
Afero simply takes the interfaces already defined throughout the standard
|
|
||||||
library and unifies them into a pair of interfaces that satisfy all
|
|
||||||
known uses. One interface for a file and one for a filesystem.
|
|
||||||
|
|
||||||
## Filesystems
|
|
||||||
|
|
||||||
Afero additionally comes with a few filesystems and file implementations
|
|
||||||
ready to use.
|
|
||||||
|
|
||||||
### OsFs
|
|
||||||
|
|
||||||
The first is simply a wrapper around the native OS calls. This makes it
|
|
||||||
very easy to use as all of the calls are the same as the existing OS
|
|
||||||
calls. It also makes it trivial to have your code use the OS during
|
|
||||||
operation and a mock filesystem during testing or as needed.
|
|
||||||
|
|
||||||
### MemMapFs
|
|
||||||
|
|
||||||
Afero also provides a fully atomic memory backed filesystem perfect for use in
|
|
||||||
mocking and to speed up unnecessary disk io when persistence isn’t
|
|
||||||
necessary. It is fully concurrent and will work within go routines
|
|
||||||
safely.
|
|
||||||
|
|
||||||
#### InMemoryFile
|
|
||||||
|
|
||||||
As part of MemMapFs, Afero also provides an atomic, fully concurrent memory
|
|
||||||
backed file implementation. This can be used in other memory backed file
|
|
||||||
systems with ease. Plans are to add a radix tree memory stored file
|
|
||||||
system using InMemoryFile.
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
|
|
||||||
### Installing
|
## Afero Features
|
||||||
Using Afero is easy. First use go get to install the latest version
|
|
||||||
of the library.
|
* A single consistent API for accessing a variety of filesystems
|
||||||
|
* Interoperation between a variety of file system types
|
||||||
|
* A set of interfaces to encourage and enforce interoperability between backends
|
||||||
|
* An atomic cross platform memory backed file system
|
||||||
|
* Support for compositional file systems by joining various different file systems (see httpFs)
|
||||||
|
|
||||||
|
|
||||||
|
# Using Afero
|
||||||
|
|
||||||
|
Afero is easy to use and easier to adopt.
|
||||||
|
|
||||||
|
A few different ways you could use Afero:
|
||||||
|
|
||||||
|
* Use the interfaces alone to define you own file system.
|
||||||
|
* Wrap for the OS packages.
|
||||||
|
* Define different filesystems for different parts of your application.
|
||||||
|
* Use Afero for mock filesystems while testing
|
||||||
|
|
||||||
|
## Step 1: Install Afero
|
||||||
|
|
||||||
|
First use go get to install the latest version of the library.
|
||||||
|
|
||||||
$ go get github.com/spf13/afero
|
$ go get github.com/spf13/afero
|
||||||
|
|
||||||
|
@ -76,13 +54,8 @@ Next include Afero in your application.
|
||||||
|
|
||||||
import "github.com/spf13/afero"
|
import "github.com/spf13/afero"
|
||||||
|
|
||||||
## Using Afero
|
|
||||||
|
|
||||||
There are a few different ways to use Afero. You could use the
|
## Step 2: Declare a backend
|
||||||
interfaces alone to define you own file system. You could use it as a
|
|
||||||
wrapper for the OS packages. You could use it to define different
|
|
||||||
filesystems for different parts of your application. Here we will
|
|
||||||
demonstrate a basic usage.
|
|
||||||
|
|
||||||
First define a package variable and set it to a pointer to a filesystem.
|
First define a package variable and set it to a pointer to a filesystem.
|
||||||
|
|
||||||
|
@ -97,8 +70,21 @@ will be using a completely new and isolated filesystem. In the case of
|
||||||
OsFs it will still use the same underlying filesystem but will reduce
|
OsFs it will still use the same underlying filesystem but will reduce
|
||||||
the ability to drop in other filesystems as desired.
|
the ability to drop in other filesystems as desired.
|
||||||
|
|
||||||
Then throughout your functions and methods use the methods familiar
|
## Step 3: Use it like you would the OS package
|
||||||
already from the OS package.
|
|
||||||
|
Throughout your application use any function and method like you normally
|
||||||
|
would.
|
||||||
|
|
||||||
|
So if my application before had:
|
||||||
|
|
||||||
|
os.Open('/tmp/foo')
|
||||||
|
|
||||||
|
We would replace it with a call to `AppFs.Open('/tmp/foo')`.
|
||||||
|
|
||||||
|
`AppFs` being the variable we defined above.
|
||||||
|
|
||||||
|
|
||||||
|
## List of all available functions
|
||||||
|
|
||||||
File System Methods Available:
|
File System Methods Available:
|
||||||
|
|
||||||
|
@ -132,27 +118,64 @@ File Interfaces and Methods Available:
|
||||||
Truncate(size int64) : error
|
Truncate(size int64) : error
|
||||||
WriteString(s string) : ret int, err error
|
WriteString(s string) : ret int, err error
|
||||||
|
|
||||||
|
|
||||||
In our case we would call `AppFs.Open()` as an example because that is how we’ve defined to
|
|
||||||
access our filesystem.
|
|
||||||
|
|
||||||
In some applications it may make sense to define a new package that
|
In some applications it may make sense to define a new package that
|
||||||
simply exports the file system variable for easy access from anywhere.
|
simply exports the file system variable for easy access from anywhere.
|
||||||
|
|
||||||
|
## Using Afero for Testing
|
||||||
|
|
||||||
### Using a Mock Filesystem for Testing
|
There is a large benefit to using a mock filesystem for testing. It has a
|
||||||
|
completely blank state every time it is initialized and can be easily
|
||||||
|
reproducible regardless of OS. You could create files to your heart’s content
|
||||||
|
and the file access would be fast while also saving you from all the annoying
|
||||||
|
issues with deleting temporary files, Windows file locking, etc. The MemMapFs
|
||||||
|
backend is perfect for testing.
|
||||||
|
|
||||||
There is a large benefit to using a mock filesystem for testing. It has
|
* Much faster than performing I/O operations on disk
|
||||||
a completely blank state every time it is initialized and can be easily
|
* Avoid security issues and permissions
|
||||||
reproducible regardless of OS. It is also faster than disk which makes
|
* Far more control. 'rm -rf /' with confidence
|
||||||
the tests run faster. Lastly it doesn’t require any clean up after tests
|
* Test setup is far more easier to do
|
||||||
are run.
|
* No test cleanup needed
|
||||||
|
|
||||||
One way to accomplish this is to define a variable as mentioned above.
|
One way to accomplish this is to define a variable as mentioned above.
|
||||||
In your application this will be set to &afero.OsFs{} during testing you
|
In your application this will be set to &afero.OsFs{} during testing you
|
||||||
can set it to &afero.MemMapFs{}.
|
can set it to &afero.MemMapFs{}.
|
||||||
|
|
||||||
### Using with Http
|
It wouldn't be uncommon to have each test initialize a blank slate memory
|
||||||
|
backend. To do this I would define my `appFS = &afero.OsFs{}` somewhere
|
||||||
|
appropriate in my application code. This approach ensures that Tests are order
|
||||||
|
independent, with no test relying on the state left by an earlier test.
|
||||||
|
|
||||||
|
Then in my tests I would initialize a new MemMapFs for each test:
|
||||||
|
|
||||||
|
func TestExist(t *testing.T) {
|
||||||
|
appFS = &afero.MemMapFs{}
|
||||||
|
// create test files and directories
|
||||||
|
appFS.MkdirAll("src/a", 0755))
|
||||||
|
appFS.WriteFile("src/a/b", []byte("file b"), 0644)
|
||||||
|
appFS.WriteFile("src/c", []byte("file c"), 0644)
|
||||||
|
testExistence("src/c", true, t)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testExistence(name string, e bool, t *testing.T) {
|
||||||
|
_, err := appFS.Stat(name)
|
||||||
|
if os.IsNotExist(err) {
|
||||||
|
if e {
|
||||||
|
t.Errorf("file \"%s\" does not exist.\n", name)
|
||||||
|
}
|
||||||
|
} else if err != nil {
|
||||||
|
panic(err)
|
||||||
|
} else {
|
||||||
|
if !e {
|
||||||
|
t.Errorf("file \"%s\" exists.\n", name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
## Using Afero with Http
|
||||||
|
|
||||||
|
Afero provides an http compatible backend which can wrap any of the existing
|
||||||
|
backends.
|
||||||
|
|
||||||
The Http package requires a slightly specific version of Open which
|
The Http package requires a slightly specific version of Open which
|
||||||
returns an http.File type.
|
returns an http.File type.
|
||||||
|
@ -164,8 +187,54 @@ Any Afero FileSystem can be used as an httpFs.
|
||||||
fileserver := http.FileServer(httpFs.Dir(<PATH>)))
|
fileserver := http.FileServer(httpFs.Dir(<PATH>)))
|
||||||
http.Handle("/", fileserver)
|
http.Handle("/", fileserver)
|
||||||
|
|
||||||
|
# Available Backends
|
||||||
|
|
||||||
|
## OsFs
|
||||||
|
|
||||||
|
The first is simply a wrapper around the native OS calls. This makes it
|
||||||
|
very easy to use as all of the calls are the same as the existing OS
|
||||||
|
calls. It also makes it trivial to have your code use the OS during
|
||||||
|
operation and a mock filesystem during testing or as needed.
|
||||||
|
|
||||||
|
## MemMapFs
|
||||||
|
|
||||||
|
Afero also provides a fully atomic memory backed filesystem perfect for use in
|
||||||
|
mocking and to speed up unnecessary disk io when persistence isn’t
|
||||||
|
necessary. It is fully concurrent and will work within go routines
|
||||||
|
safely.
|
||||||
|
|
||||||
|
### InMemoryFile
|
||||||
|
|
||||||
|
As part of MemMapFs, Afero also provides an atomic, fully concurrent memory
|
||||||
|
backed file implementation. This can be used in other memory backed file
|
||||||
|
systems with ease. Plans are to add a radix tree memory stored file
|
||||||
|
system using InMemoryFile.
|
||||||
|
|
||||||
|
## Desired/possible backends
|
||||||
|
|
||||||
|
The following is a short list of possible backends we hope someone will
|
||||||
|
implement:
|
||||||
|
|
||||||
|
* SSH/SCP
|
||||||
|
* ZIP
|
||||||
|
* TAR
|
||||||
|
* S3
|
||||||
|
* Mem buffering to disk/network
|
||||||
|
* BasePath (where all paths are relative to a fixed basepath)
|
||||||
|
|
||||||
|
# About the project
|
||||||
|
|
||||||
|
## The name
|
||||||
|
|
||||||
|
Initially this project was called fs. Unfortunately as I used it, the
|
||||||
|
name proved confusing, there were too many fs’. In looking for
|
||||||
|
alternatives I looked up the word 'abstract' in a variety of different
|
||||||
|
languages. Afero is the Greek word for abstract and it seemed to be a
|
||||||
|
fitting name for the project. It also means ‘to do’ or ‘thing’ in
|
||||||
|
Esperanto which is also fitting.
|
||||||
|
|
||||||
## Release Notes
|
## Release Notes
|
||||||
|
|
||||||
* **0.9.0** 2015.11.05
|
* **0.9.0** 2015.11.05
|
||||||
* New Walk function similar to filepath.Walk
|
* New Walk function similar to filepath.Walk
|
||||||
* MemMapFs.OpenFile handles O_CREATE, O_APPEND, O_TRUNC
|
* MemMapFs.OpenFile handles O_CREATE, O_APPEND, O_TRUNC
|
||||||
|
@ -198,4 +267,5 @@ Names in no particular order:
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
Afero is released under the Apache 2.0 license. See [LICENSE.txt](https://github.com/spf13/afero/blob/master/LICENSE.txt)
|
Afero is released under the Apache 2.0 license. See
|
||||||
|
[LICENSE.txt](https://github.com/spf13/afero/blob/master/LICENSE.txt)
|
||||||
|
|
Loading…
Reference in New Issue