Skip to content

Commit

Permalink
Fix Chown() pull request errors
Browse files Browse the repository at this point in the history
  • Loading branch information
mfuterko committed Dec 7, 2020
2 parents 30c3c32 + 736b98e commit cb1d580
Show file tree
Hide file tree
Showing 41 changed files with 2,110 additions and 258 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
sftpfs/file1
sftpfs/test/
46 changes: 25 additions & 21 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,21 +1,25 @@
sudo: false
language: go

go:
- 1.9
- "1.10"
- tip

os:
- linux
- osx

matrix:
allow_failures:
- go: tip
fast_finish: true

script:
- go build
- go test -race -v ./...

sudo: false
language: go
arch:
- amd64
- ppc64e

go:
- "1.13"
- "1.14"
- tip

os:
- linux
- osx

matrix:
allow_failures:
- go: tip
fast_finish: true

script:
- go build -v ./...
- go test -count=1 -cover -race -v ./...
- go vet ./...
- FILES=$(gofmt -s -l . zipfs sftpfs mem tarfs); if [[ -n "${FILES}" ]]; then echo "You have go format errors; gofmt your changes"; exit 1; fi
39 changes: 8 additions & 31 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ A FileSystem Abstraction System for Go

# Overview

Afero is an filesystem framework providing a simple, uniform and universal API
Afero is a filesystem framework providing a simple, uniform and universal API
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.
Expand All @@ -18,7 +18,7 @@ and benefit of the os and ioutil packages.
Afero provides significant improvements over using the os package alone, most
notably the ability to create mock and testing filesystems without relying on the disk.

It is suitable for use in a any situation where you would consider using the OS
It is suitable for use in any situation where you would consider using the OS
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
filesystem for full interoperability.
Expand All @@ -41,8 +41,8 @@ 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.
* Use the interfaces alone to define your own file system.
* Wrapper for the OS packages.
* Define different filesystems for different parts of your application.
* Use Afero for mock filesystems while testing

Expand Down Expand Up @@ -227,7 +227,7 @@ operation and a mock filesystem during testing or as needed.

```go
appfs := afero.NewOsFs()
appfs.MkdirAll("src/a", 0755))
appfs.MkdirAll("src/a", 0755)
```

## Memory Backed Storage
Expand All @@ -241,7 +241,7 @@ safely.

```go
mm := afero.NewMemMapFs()
mm.MkdirAll("src/a", 0755))
mm.MkdirAll("src/a", 0755)
```

#### InMemoryFile
Expand Down Expand Up @@ -306,7 +306,7 @@ Any Afero FileSystem can be used as an httpFs.

```go
httpFs := afero.NewHttpFs(<ExistingFS>)
fileserver := http.FileServer(httpFs.Dir(<PATH>)))
fileserver := http.FileServer(httpFs.Dir(<PATH>))
http.Handle("/", fileserver)
```

Expand Down Expand Up @@ -380,8 +380,6 @@ The following is a short list of possible backends we hope someone will
implement:

* SSH
* ZIP
* TAR
* S3

# About the project
Expand All @@ -406,28 +404,7 @@ Googles very well.

## Release Notes

* **0.10.0** 2015.12.10
* Full compatibility with Windows
* Introduction of afero utilities
* Test suite rewritten to work cross platform
* Normalize paths for MemMapFs
* Adding Sync to the file interface
* **Breaking Change** Walk and ReadDir have changed parameter order
* Moving types used by MemMapFs to a subpackage
* General bugfixes and improvements
* **0.9.0** 2015.11.05
* New Walk function similar to filepath.Walk
* MemMapFs.OpenFile handles O_CREATE, O_APPEND, O_TRUNC
* MemMapFs.Remove now really deletes the file
* InMemoryFile.Readdir and Readdirnames work correctly
* InMemoryFile functions lock it for concurrent access
* Test suite improvements
* **0.8.0** 2014.10.28
* First public version
* Interfaces feel ready for people to build using
* Interfaces satisfy all known uses
* MemMapFs passes the majority of the OS test suite
* OsFs passes the majority of the OS test suite
See the [Releases Page](https://github.com/spf13/afero/releases).

## Contributing

Expand Down
8 changes: 4 additions & 4 deletions afero.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,14 +91,14 @@ type Fs interface {
// The name of this FileSystem
Name() string

//Chmod changes the mode of the named file to mode.
// Chmod changes the mode of the named file to mode.
Chmod(name string, mode os.FileMode) error

// Chown changes the uid and gid of the named file.
Chown(name string, uid, gid int) error

//Chtimes changes the access and modification times of the named file
Chtimes(name string, atime time.Time, mtime time.Time) error

// Chown changes uid and gid of the named file.
Chown(name string, uid, gid int) error
}

var (
Expand Down
4 changes: 2 additions & 2 deletions appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ build_script:
go get -v github.com/spf13/afero/...
go build github.com/spf13/afero
go build -v github.com/spf13/afero/...
test_script:
- cmd: go test -race -v github.com/spf13/afero/...
- cmd: go test -count=1 -cover -race -v github.com/spf13/afero/...
34 changes: 29 additions & 5 deletions basepath.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,13 @@ func (b *BasePathFs) Chmod(name string, mode os.FileMode) (err error) {
return b.source.Chmod(name, mode)
}

func (b *BasePathFs) Chown(name string, uid, gid int) (err error) {
if name, err = b.RealPath(name); err != nil {
return &os.PathError{Op: "chown", Path: name, Err: err}
}
return b.source.Chown(name, uid, gid)
}

func (b *BasePathFs) Name() string {
return "BasePathFs"
}
Expand Down Expand Up @@ -177,11 +184,28 @@ func (b *BasePathFs) LstatIfPossible(name string) (os.FileInfo, bool, error) {
return fi, false, err
}

func (b *BasePathFs) SymlinkIfPossible(oldname, newname string) error {
oldname, err := b.RealPath(oldname)
if err != nil {
return &os.LinkError{Op: "symlink", Old: oldname, New: newname, Err: err}
}
newname, err = b.RealPath(newname)
if err != nil {
return &os.LinkError{Op: "symlink", Old: oldname, New: newname, Err: err}
}
if linker, ok := b.source.(Linker); ok {
return linker.SymlinkIfPossible(oldname, newname)
}
return &os.LinkError{Op: "symlink", Old: oldname, New: newname, Err: ErrNoSymlink}
}

func (b *BasePathFs) Chown(name string, uid, gid int) (err error) {
if name, err = b.RealPath(name); err != nil {
return &os.PathError{Op: "chown", Path: name, Err: err}
func (b *BasePathFs) ReadlinkIfPossible(name string) (string, error) {
name, err := b.RealPath(name)
if err != nil {
return "", &os.PathError{Op: "readlink", Path: name, Err: err}
}
return b.source.Chown(name, uid, gid)
if reader, ok := b.source.(LinkReader); ok {
return reader.ReadlinkIfPossible(name)
}
return "", &os.PathError{Op: "readlink", Path: name, Err: ErrNoReadlink}
}
// vim: ts=4 sw=4 noexpandtab nolist syn=go
14 changes: 7 additions & 7 deletions basepath_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,10 +96,10 @@ func TestNestedBasePaths(t *testing.T) {
Dir1, Dir2, Dir3 string
}
dirSpecs := []dirSpec{
dirSpec{Dir1: "/", Dir2: "/", Dir3: "/"},
dirSpec{Dir1: "/", Dir2: "/path2", Dir3: "/"},
dirSpec{Dir1: "/path1/dir", Dir2: "/path2/dir/", Dir3: "/path3/dir"},
dirSpec{Dir1: "C:/path1", Dir2: "path2/dir", Dir3: "/path3/dir/"},
{Dir1: "/", Dir2: "/", Dir3: "/"},
{Dir1: "/", Dir2: "/path2", Dir3: "/"},
{Dir1: "/path1/dir", Dir2: "/path2/dir/", Dir3: "/path3/dir"},
{Dir1: "C:/path1", Dir2: "path2/dir", Dir3: "/path3/dir/"},
}

for _, ds := range dirSpecs {
Expand All @@ -113,9 +113,9 @@ func TestNestedBasePaths(t *testing.T) {
FileName string
}
specs := []spec{
spec{BaseFs: level3Fs, FileName: "f.txt"},
spec{BaseFs: level2Fs, FileName: "f.txt"},
spec{BaseFs: level1Fs, FileName: "f.txt"},
{BaseFs: level3Fs, FileName: "f.txt"},
{BaseFs: level2Fs, FileName: "f.txt"},
{BaseFs: level1Fs, FileName: "f.txt"},
}

for _, s := range specs {
Expand Down
42 changes: 21 additions & 21 deletions cacheOnReadFs.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,27 @@ func (u *CacheOnReadFs) Chmod(name string, mode os.FileMode) error {
return u.layer.Chmod(name, mode)
}

func (u *CacheOnReadFs) Chown(name string, uid, gid int) error {
st, _, err := u.cacheStatus(name)
if err != nil {
return err
}
switch st {
case cacheLocal:
case cacheHit:
err = u.base.Chown(name, uid, gid)
case cacheStale, cacheMiss:
if err := u.copyToLayer(name); err != nil {
return err
}
err = u.base.Chown(name, uid, gid)
}
if err != nil {
return err
}
return u.layer.Chown(name, uid, gid)
}

func (u *CacheOnReadFs) Stat(name string) (os.FileInfo, error) {
st, fi, err := u.cacheStatus(name)
if err != nil {
Expand Down Expand Up @@ -288,24 +309,3 @@ func (u *CacheOnReadFs) Create(name string) (File, error) {
}
return &UnionFile{Base: bfh, Layer: lfh}, nil
}

func (u *CacheOnReadFs) Chown(name string, uid, gid int) error {
st, _, err := u.cacheStatus(name)
if err != nil {
return err
}
switch st {
case cacheLocal:
case cacheHit:
err = u.base.Chown(name, uid, gid)
case cacheStale, cacheMiss:
if err := u.copyToLayer(name); err != nil {
return err
}
err = u.base.Chown(name, uid, gid)
}
if err != nil {
return err
}
return u.layer.Chown(name, uid, gid)
}
20 changes: 16 additions & 4 deletions composite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -477,7 +477,8 @@ func TestUnionFileReaddirAskForTooMany(t *testing.T) {
base := &MemMapFs{}
overlay := &MemMapFs{}

for i := 0; i < 5; i++ {
const testFiles = 5
for i := 0; i < testFiles; i++ {
WriteFile(base, fmt.Sprintf("file%d.txt", i), []byte("afero"), 0777)
}

Expand All @@ -490,13 +491,24 @@ func TestUnionFileReaddirAskForTooMany(t *testing.T) {

defer f.Close()

names, err := f.Readdirnames(6)
// Read part of all files
wantNames := 3
names, err := f.Readdirnames(wantNames)
if err != nil {
t.Fatal(err)
}
if len(names) != wantNames {
t.Fatalf("got %d names %v, want %d", len(names), names, wantNames)
}

if len(names) != 5 {
t.Fatal(names)
// Try to read more files than remaining
wantNames = testFiles - len(names)
names, err = f.Readdirnames(wantNames + 1)
if err != nil {
t.Fatal(err)
}
if len(names) != wantNames {
t.Fatalf("got %d names %v, want %d", len(names), names, wantNames)
}

// End of directory
Expand Down
2 changes: 1 addition & 1 deletion const_bsds.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

// +build darwin openbsd freebsd netbsd dragonfly
// +build aix darwin openbsd freebsd netbsd dragonfly

package afero

Expand Down
1 change: 1 addition & 0 deletions const_win_unix.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
// +build !freebsd
// +build !dragonfly
// +build !netbsd
// +build !aix

package afero

Expand Down
Loading

0 comments on commit cb1d580

Please sign in to comment.