From c4c108be8160cbe93a03d2b37bc113d51093f057 Mon Sep 17 00:00:00 2001 From: Jan Seidl Date: Tue, 11 Apr 2017 23:38:02 +0200 Subject: [PATCH 01/54] split to more files --- constructor.go | 44 ++++++++++++++++++++ copy.go | 64 +++++++++++++++++++++++++++++ copy_test.go | 109 +++++++++++++++++++++++++++++++++++++++++++++++++ stat.go | 51 +++++++++++++++++++++++ struct.go | 15 +++++++ 5 files changed, 283 insertions(+) create mode 100644 constructor.go create mode 100644 copy.go create mode 100644 copy_test.go create mode 100644 stat.go create mode 100644 struct.go diff --git a/constructor.go b/constructor.go new file mode 100644 index 0000000..34bcdbb --- /dev/null +++ b/constructor.go @@ -0,0 +1,44 @@ +package path + +import ( + "io/ioutil" + "os" + "path/filepath" +) + +// NewPath construct *Path +// +// for example +// path := NewPath("/home/test", ".vimrc") +// +func NewPath(path ...string) *Path { + newPath := new(Path) + newPath.Path = filepath.Join(path...) + + return newPath +} + +// NewTempFile create temp file +// +// for delete after scope use defer +// temp, err := NewTempFile(TempFileOpt{}) +// defer temp.Remove() + +func NewTempFile(options TempFileOpt) (*Path, error) { + dir := options.Dir + + if dir == "" { + dir = os.TempDir() + } + + file, err := ioutil.TempFile(dir, options.Prefix) + + if err != nil { + return nil, err + } + + return &Path{ + file: file, + Path: file.Name(), + }, nil +} diff --git a/copy.go b/copy.go new file mode 100644 index 0000000..8d7176f --- /dev/null +++ b/copy.go @@ -0,0 +1,64 @@ +package path + +import ( + "io" + "os" + "path/filepath" +) + +// Remove file +// err := path.Remove() +// like os.Remove + +func (path *Path) Remove() error { + path.file = nil + return os.Remove(path.Path) +} + +// Remove tree of files +// err := path.RemoveTree +// like os.RemoveAll +func (path *Path) RemoveTree() error { + path.file = nil + return os.RemoveAll(path.Path) +} + +func (path *Path) String() string { + return filepath.Clean(path.Path) +} + +func (path *Path) Basename() string { + return filepath.Base(path.Path) +} + +func (path *Path) CopyFile(dst string) (*Path, error) { + if isDir, _ := NewPath(dst).IsDir(); isDir { + dst = NewPath(dst, path.Basename()).String() + } + + originalFile, err := os.Open(path.String()) + if err != nil { + return nil, err + } + defer originalFile.Close() + + newFile, err := os.Create(dst) + if err != nil { + return nil, err + } + defer newFile.Close() + + _, err = io.Copy(newFile, originalFile) + if err != nil { + return nil, err + } + + // Commit the file contents + // Flushes memory to disk + err = newFile.Sync() + if err != nil { + return nil, err + } + + return NewPath(dst), nil +} diff --git a/copy_test.go b/copy_test.go new file mode 100644 index 0000000..6a6cdd7 --- /dev/null +++ b/copy_test.go @@ -0,0 +1,109 @@ +package path + +import ( + "github.com/stretchr/testify/assert" + "os" + "testing" +) + +func TestString(t *testing.T) { + assert.Equal(t, "/tmp/test", NewPath("/tmp/test").String(), "string") + assert.Equal(t, "/tmp/test", NewPath("/tmp/test/").String(), "string") + + assert.Equal(t, "/tmp/test", NewPath("/tmp", "test").String(), "string") + assert.Equal(t, "/tmp/test", NewPath("/tmp", NewPath("test").String()).String(), "string") +} + +func TestBasename(t *testing.T) { + assert.Equal(t, "test", NewPath("/tmp/test").Basename(), "basename of /tmp/test") + assert.Equal(t, "", NewPath("/").Basename(), "basename of root") +} + +func TestExists(t *testing.T) { + assert.Exactly(t, true, NewPath("copy_test.go").Exists(), "this test exists") + assert.Exactly(t, false, NewPath("/sdlkfjsflsjfsl").Exists(), "wired root dir don't exists") + assert.Exactly(t, true, NewPath(os.TempDir()).Exists(), "home dir exists") +} + +func TestTempFile(t *testing.T) { + temp, err := NewTempFile(TempFileOpt{Prefix: "bla"}) + defer temp.Remove() + + assert.NotNil(t, temp) + assert.Nil(t, err) + assert.Exactly(t, true, temp.Exists(), "new temp file exists") +} + +func TestIsDir(t *testing.T) { + isDir, err := NewPath(os.TempDir()).IsDir() + assert.Nil(t, err) + assert.Exactly(t, true, isDir, "temp dir is dir") + + isDir, err = NewPath("copy_test.go").IsDir() + assert.Nil(t, err) + assert.Exactly(t, false, isDir, "this test file isn't dir") + + isDir, err = NewPath("/safjasfjalfja").IsDir() + assert.NotNil(t, err) + assert.Exactly(t, false, isDir, "unexists somethings isn't dir") +} + +func TestIsFile(t *testing.T) { + isFile, err := NewPath(os.TempDir()).IsFile() + assert.Nil(t, err) + assert.Exactly(t, false, isFile, "temp dir is dir - no file") + + isFile, err = NewPath("copy_test.go").IsFile() + assert.Nil(t, err) + assert.Exactly(t, true, isFile, "this test file is file") + + isFile, err = NewPath("/safjasfjalfja").IsFile() + assert.NotNil(t, err) + assert.Exactly(t, false, isFile, "unexists somethings isn't file") +} + +func TestCopyFile(t *testing.T) { + t.Run("dst file not exists", + func(t *testing.T) { + src := NewPath("copy_test.go") + dst, err := NewTempFile(TempFileOpt{}) + assert.Nil(t, err) + defer dst.Remove() + dst.Remove() + + assert.Exactly(t, false, dst.Exists(), "dst file isn't exists") + newDst, err := src.CopyFile(dst.String()) + assert.Nil(t, err) + assert.Equal(t, dst.String(), newDst.String(), "dst file is same as what return CopyFile") + assert.Exactly(t, true, newDst.Exists(), "dst file after copy exists") + }) + + t.Run("dst file exists", + func(t *testing.T) { + src := NewPath("copy_test.go") + dst, err := NewTempFile(TempFileOpt{}) + assert.Nil(t, err) + defer dst.Remove() + + assert.Exactly(t, true, dst.Exists(), "dst file exists before copy") + newDst, err := src.CopyFile(dst.String()) + assert.Nil(t, err) + assert.Equal(t, dst.String(), newDst.String(), "dst file is same as what return CopyFile") + assert.Exactly(t, true, newDst.Exists(), "dst file after copy exists") + }) + + t.Run("dst is dir", + func(t *testing.T) { + src := NewPath("copy_test.go") + dst := NewPath(os.TempDir()) + + assert.Exactly(t, true, dst.Exists(), "dst dir exists") + newDst, err := src.CopyFile(dst.String()) + defer newDst.Remove() + + assert.Nil(t, err) + assert.Exactly(t, true, newDst.Exists(), "dst file after copy exists") + assert.Equal(t, src.Basename(), newDst.Basename(), "if is dst directory, then is used basename of source") + }) + +} diff --git a/stat.go b/stat.go new file mode 100644 index 0000000..fb3caaa --- /dev/null +++ b/stat.go @@ -0,0 +1,51 @@ +package path + +import ( + "fmt" + "os" +) + +func (path *Path) Stat() (os.FileInfo, error) { + file, err := os.Open(path.Path) + + if err != nil { + return nil, err + } + + defer func() { + if err := file.Close(); err != nil { + fmt.Println(err) + } + }() + + return file.Stat() +} + +// File or dir exists + +func (path *Path) Exists() bool { + if _, err := path.Stat(); os.IsNotExist(err) { + return false + } + + return true +} + +// IsDir return true if path is dir +func (path *Path) IsDir() (bool, error) { + stat, err := path.Stat() + if err != nil { + return false, err + } + + return stat.IsDir(), nil +} + +func (path *Path) IsFile() (bool, error) { + stat, err := path.Stat() + if err != nil { + return false, err + } + + return stat.Mode().IsRegular(), nil +} diff --git a/struct.go b/struct.go new file mode 100644 index 0000000..7215cd2 --- /dev/null +++ b/struct.go @@ -0,0 +1,15 @@ +package path + +import ( + "os" +) + +type Path struct { + Path string + file *os.File +} + +type TempFileOpt struct { + Dir string + Prefix string +} From 473ec29abd380ad6dfd1e6270486da651421368b Mon Sep 17 00:00:00 2001 From: Jan Seidl Date: Wed, 12 Apr 2017 00:26:04 +0200 Subject: [PATCH 02/54] add CI build on linux (travis) and appveyor (windows) --- .travis.yml | 7 +++++++ appveyor.yml | 14 ++++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 .travis.yml create mode 100644 appveyor.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..69d2f6d --- /dev/null +++ b/.travis.yml @@ -0,0 +1,7 @@ +language: go + +go: + - 1.x + - 1.6 + - 1.7.x + - master diff --git a/appveyor.yml b/appveyor.yml new file mode 100644 index 0000000..5dd982f --- /dev/null +++ b/appveyor.yml @@ -0,0 +1,14 @@ +version: "{build}" + +#os: Windows Server 2012 R2 +platform: x64 + +install: + - echo %PATH% + - echo %GOPATH% + - go version + - go env + - go get -v -t + +build_script: + - go test -v From 5036236fe85d7fdfda81c4b6086dc53465437ecb Mon Sep 17 00:00:00 2001 From: Jan Seidl Date: Wed, 12 Apr 2017 00:31:51 +0200 Subject: [PATCH 03/54] fix appveyor --- appveyor.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 5dd982f..1a4a667 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,11 +1,11 @@ version: "{build}" +clone_folder: c:\go\src\github.com\jasei\path-go + #os: Windows Server 2012 R2 platform: x64 install: - - echo %PATH% - - echo %GOPATH% - go version - go env - go get -v -t From 57e22a6ccf918183752abdb102844a1afff7a4b3 Mon Sep 17 00:00:00 2001 From: Jan Seidl Date: Wed, 12 Apr 2017 17:04:50 +0200 Subject: [PATCH 04/54] add badges --- README.md | 3 +++ copy.go | 3 +-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index d93eedf..161b6fc 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,6 @@ # path-go +[![Build Status](https://travis-ci.org/JaSei/path-go.svg?branch=implementation)](https://travis-ci.org/JaSei/path-go) +[![Build status](https://ci.appveyor.com/api/projects/status/urj0cf370sr5hjw4?svg=true)](https://ci.appveyor.com/project/JaSei/path-go) + File path utility inspired by David Golden's [Path::Tiny](https://metacpan.org/pod/Path::Tiny) diff --git a/copy.go b/copy.go index 8d7176f..f2acf0b 100644 --- a/copy.go +++ b/copy.go @@ -42,8 +42,7 @@ func (path *Path) CopyFile(dst string) (*Path, error) { } defer originalFile.Close() - newFile, err := os.Create(dst) - if err != nil { + if newFile, err := os.Create(dst); err != nil { return nil, err } defer newFile.Close() From b1e6ea56041e518081a8bb5d4e73c16a1f3d14bd Mon Sep 17 00:00:00 2001 From: Jan Seidl Date: Wed, 12 Apr 2017 17:22:52 +0200 Subject: [PATCH 05/54] add badges --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 161b6fc..de6eda5 100644 --- a/README.md +++ b/README.md @@ -2,5 +2,7 @@ [![Build Status](https://travis-ci.org/JaSei/path-go.svg?branch=implementation)](https://travis-ci.org/JaSei/path-go) [![Build status](https://ci.appveyor.com/api/projects/status/urj0cf370sr5hjw4?svg=true)](https://ci.appveyor.com/project/JaSei/path-go) +[![Go Report Card](https://goreportcard.com/badge/github.com/JaSei/path-go)](https://goreportcard.com/report/github.com/JaSei/path-go) +[![GoDoc](https://godoc.org/github.com/JaSei/path-go?status.svg)](http://godoc.org/github.com/jasei/path-go) File path utility inspired by David Golden's [Path::Tiny](https://metacpan.org/pod/Path::Tiny) From 3e53da7126d043cfee69f528db4d130f9981cfca Mon Sep 17 00:00:00 2001 From: Jan Seidl Date: Fri, 14 Apr 2017 01:05:26 +0200 Subject: [PATCH 06/54] more tests --- constructor.go | 12 +++++-- constructor_test.go | 28 +++++++++++++++ copy.go | 27 ++++++++++---- copy_test.go | 88 ++++++++++++++++++++------------------------- stat.go | 21 +++++++---- stat_test.go | 59 ++++++++++++++++++++++++++++++ 6 files changed, 171 insertions(+), 64 deletions(-) create mode 100644 constructor_test.go create mode 100644 stat_test.go diff --git a/constructor.go b/constructor.go index 34bcdbb..e4f7574 100644 --- a/constructor.go +++ b/constructor.go @@ -1,6 +1,7 @@ package path import ( + "errors" "io/ioutil" "os" "path/filepath" @@ -11,16 +12,20 @@ import ( // for example // path := NewPath("/home/test", ".vimrc") // -func NewPath(path ...string) *Path { +func NewPath(path ...string) (*Path, error) { newPath := new(Path) newPath.Path = filepath.Join(path...) - return newPath + if len(newPath.Path) == 0 { + return nil, errors.New("Paths requires defined, positive-lengths parts") + } + + return newPath, nil } // NewTempFile create temp file // -// for delete after scope use defer +// for cleanup use defer // temp, err := NewTempFile(TempFileOpt{}) // defer temp.Remove() @@ -32,6 +37,7 @@ func NewTempFile(options TempFileOpt) (*Path, error) { } file, err := ioutil.TempFile(dir, options.Prefix) + defer file.Close() if err != nil { return nil, err diff --git a/constructor_test.go b/constructor_test.go new file mode 100644 index 0000000..5e91d46 --- /dev/null +++ b/constructor_test.go @@ -0,0 +1,28 @@ +package path + +import ( + "github.com/stretchr/testify/assert" + "testing" +) + +func TestNewPath(t *testing.T) { + path, err := NewPath("") + assert.Nil(t, path) + assert.NotNil(t, err) + + path, err = NewPath("test") + assert.NotNil(t, path) + assert.Nil(t, err) +} + +func TestNewTempFile(t *testing.T) { + temp, err := NewTempFile(TempFileOpt{}) + defer temp.Remove() + assert.NotNil(t, temp) + assert.Nil(t, err) + + temp, err = NewTempFile(TempFileOpt{Dir: "."}) + defer temp.Remove() + assert.NotNil(t, temp) + assert.Nil(t, err) +} diff --git a/copy.go b/copy.go index f2acf0b..24f13ce 100644 --- a/copy.go +++ b/copy.go @@ -28,21 +28,36 @@ func (path *Path) String() string { } func (path *Path) Basename() string { + if path.Path == "/" { + return "" + } + return filepath.Base(path.Path) } -func (path *Path) CopyFile(dst string) (*Path, error) { - if isDir, _ := NewPath(dst).IsDir(); isDir { - dst = NewPath(dst, path.Basename()).String() +func (srcPath *Path) CopyFile(dst string) (*Path, error) { + dstPath, err := NewPath(dst) + if err != nil { + return nil, err } - originalFile, err := os.Open(path.String()) + if dstPath.IsDir() { + dstPath, err := NewPath(dst, srcPath.Basename()) + if err != nil { + return nil, err + } else { + dst = dstPath.String() + } + } + + originalFile, err := os.Open(srcPath.String()) if err != nil { return nil, err } defer originalFile.Close() - if newFile, err := os.Create(dst); err != nil { + newFile, err := os.Create(dst) + if err != nil { return nil, err } defer newFile.Close() @@ -59,5 +74,5 @@ func (path *Path) CopyFile(dst string) (*Path, error) { return nil, err } - return NewPath(dst), nil + return NewPath(dst) } diff --git a/copy_test.go b/copy_test.go index 6a6cdd7..7e9e247 100644 --- a/copy_test.go +++ b/copy_test.go @@ -7,22 +7,28 @@ import ( ) func TestString(t *testing.T) { - assert.Equal(t, "/tmp/test", NewPath("/tmp/test").String(), "string") - assert.Equal(t, "/tmp/test", NewPath("/tmp/test/").String(), "string") + path, _ := NewPath("/tmp/test") + assert.Equal(t, "/tmp/test", path.String(), "string") - assert.Equal(t, "/tmp/test", NewPath("/tmp", "test").String(), "string") - assert.Equal(t, "/tmp/test", NewPath("/tmp", NewPath("test").String()).String(), "string") + path, _ = NewPath("/tmp/test/") + assert.Equal(t, "/tmp/test", path.String(), "string") + + path, _ = NewPath("/tmp", "test") + assert.Equal(t, "/tmp/test", path.String(), "string") } func TestBasename(t *testing.T) { - assert.Equal(t, "test", NewPath("/tmp/test").Basename(), "basename of /tmp/test") - assert.Equal(t, "", NewPath("/").Basename(), "basename of root") -} + path, _ := NewPath("/tmp/test") + assert.Equal(t, "test", path.Basename(), "basename of /tmp/test") + + path, _ = NewPath("/") + assert.Equal(t, "", path.Basename(), "basename of root") + + path, _ = NewPath("relative") + assert.Equal(t, "relative", path.Basename(), "relative basename") -func TestExists(t *testing.T) { - assert.Exactly(t, true, NewPath("copy_test.go").Exists(), "this test exists") - assert.Exactly(t, false, NewPath("/sdlkfjsflsjfsl").Exists(), "wired root dir don't exists") - assert.Exactly(t, true, NewPath(os.TempDir()).Exists(), "home dir exists") + path, _ = NewPath("relative/a") + assert.Equal(t, "a", path.Basename(), "relative subpath basename") } func TestTempFile(t *testing.T) { @@ -34,38 +40,12 @@ func TestTempFile(t *testing.T) { assert.Exactly(t, true, temp.Exists(), "new temp file exists") } -func TestIsDir(t *testing.T) { - isDir, err := NewPath(os.TempDir()).IsDir() - assert.Nil(t, err) - assert.Exactly(t, true, isDir, "temp dir is dir") - - isDir, err = NewPath("copy_test.go").IsDir() - assert.Nil(t, err) - assert.Exactly(t, false, isDir, "this test file isn't dir") - - isDir, err = NewPath("/safjasfjalfja").IsDir() - assert.NotNil(t, err) - assert.Exactly(t, false, isDir, "unexists somethings isn't dir") -} - -func TestIsFile(t *testing.T) { - isFile, err := NewPath(os.TempDir()).IsFile() - assert.Nil(t, err) - assert.Exactly(t, false, isFile, "temp dir is dir - no file") - - isFile, err = NewPath("copy_test.go").IsFile() - assert.Nil(t, err) - assert.Exactly(t, true, isFile, "this test file is file") - - isFile, err = NewPath("/safjasfjalfja").IsFile() - assert.NotNil(t, err) - assert.Exactly(t, false, isFile, "unexists somethings isn't file") -} - func TestCopyFile(t *testing.T) { t.Run("dst file not exists", func(t *testing.T) { - src := NewPath("copy_test.go") + src, err := NewPath("copy_test.go") + assert.Nil(t, err) + dst, err := NewTempFile(TempFileOpt{}) assert.Nil(t, err) defer dst.Remove() @@ -74,36 +54,46 @@ func TestCopyFile(t *testing.T) { assert.Exactly(t, false, dst.Exists(), "dst file isn't exists") newDst, err := src.CopyFile(dst.String()) assert.Nil(t, err) - assert.Equal(t, dst.String(), newDst.String(), "dst file is same as what return CopyFile") - assert.Exactly(t, true, newDst.Exists(), "dst file after copy exists") + if err != nil { + t.Log(err) + } else { + assert.Equal(t, dst.String(), newDst.String(), "dst file is same as what return CopyFile") + assert.Exactly(t, true, newDst.Exists(), "dst file after copy exists") + } }) t.Run("dst file exists", func(t *testing.T) { - src := NewPath("copy_test.go") + src, _ := NewPath("copy_test.go") dst, err := NewTempFile(TempFileOpt{}) assert.Nil(t, err) defer dst.Remove() assert.Exactly(t, true, dst.Exists(), "dst file exists before copy") newDst, err := src.CopyFile(dst.String()) - assert.Nil(t, err) + if !assert.Nil(t, err) { + return + } + assert.Equal(t, dst.String(), newDst.String(), "dst file is same as what return CopyFile") assert.Exactly(t, true, newDst.Exists(), "dst file after copy exists") }) t.Run("dst is dir", func(t *testing.T) { - src := NewPath("copy_test.go") - dst := NewPath(os.TempDir()) + src, _ := NewPath("copy_test.go") + dst, _ := NewPath(os.TempDir()) assert.Exactly(t, true, dst.Exists(), "dst dir exists") newDst, err := src.CopyFile(dst.String()) + if !assert.Nil(t, err) { + return + } + defer newDst.Remove() - assert.Nil(t, err) - assert.Exactly(t, true, newDst.Exists(), "dst file after copy exists") + assert.Exactly(t, true, newDst.Exists(), "dst after copy exists") + assert.Exactly(t, true, newDst.IsFile(), "dst is file") assert.Equal(t, src.Basename(), newDst.Basename(), "if is dst directory, then is used basename of source") }) - } diff --git a/stat.go b/stat.go index fb3caaa..999577e 100644 --- a/stat.go +++ b/stat.go @@ -5,6 +5,7 @@ import ( "os" ) +// Stat return os.FileInfo func (path *Path) Stat() (os.FileInfo, error) { file, err := os.Open(path.Path) @@ -32,20 +33,28 @@ func (path *Path) Exists() bool { } // IsDir return true if path is dir -func (path *Path) IsDir() (bool, error) { +func (path *Path) IsDir() bool { stat, err := path.Stat() if err != nil { - return false, err + return false } - return stat.IsDir(), nil + return stat.IsDir() +} + +// IsFile return true is path exists and not dir +// (symlinks, devs, regular files) +func (path *Path) IsFile() bool { + return path.Exists() && !path.IsDir() } -func (path *Path) IsFile() (bool, error) { +// IsRegularFile return true if path is regular file +// (wihtout devs, symlinks, ...) +func (path *Path) IsRegularFile() bool { stat, err := path.Stat() if err != nil { - return false, err + return false } - return stat.Mode().IsRegular(), nil + return stat.Mode().IsRegular() } diff --git a/stat_test.go b/stat_test.go new file mode 100644 index 0000000..84f7d5a --- /dev/null +++ b/stat_test.go @@ -0,0 +1,59 @@ +package path + +import ( + "github.com/stretchr/testify/assert" + "os" + "testing" +) + +func TestExists(t *testing.T) { + path, _ := NewPath("copy_test.go") + assert.Exactly(t, true, path.Exists(), "this test exists") + path, _ = NewPath("/sdlkfjsflsjfsl") + assert.Exactly(t, false, path.Exists(), "wired root dir don't exists") + path, _ = NewPath(os.TempDir()) + assert.Exactly(t, true, path.Exists(), "home dir exists") +} + +func TestIsDir(t *testing.T) { + path, _ := NewPath(os.TempDir()) + assert.Exactly(t, true, path.IsDir(), "temp dir is dir") + + path, _ = NewPath("copy_test.go") + assert.Exactly(t, false, path.IsDir(), "this test file isn't dir") + + path, _ = NewPath("/safjasfjalfja") + assert.Exactly(t, false, path.IsDir(), "unexists somethings isn't dir") +} + +func TestIsFile(t *testing.T) { + path, _ := NewPath(os.TempDir()) + assert.Exactly(t, false, path.IsFile(), "temp dir is dir - no file") + + path, _ = NewPath("copy_test.go") + assert.Exactly(t, true, path.IsFile(), "this test file is file") + + path, _ = NewPath("/safjasfjalfja") + assert.Exactly(t, false, path.IsFile(), "unexists somethings isn't file") + + path, _ = NewPath("/dev/zero") + assert.Exactly(t, true, path.IsFile(), "/dev/zero is file") + + //symlink test +} + +func TestIsRegularFile(t *testing.T) { + path, _ := NewPath(os.TempDir()) + assert.Exactly(t, false, path.IsRegularFile(), "temp dir is dir - no file") + + path, _ = NewPath("copy_test.go") + assert.Exactly(t, true, path.IsRegularFile(), "this test file is file") + + path, _ = NewPath("/safjasfjalfja") + assert.Exactly(t, false, path.IsRegularFile(), "unexists somethings isn't file") + + path, _ = NewPath("/dev/zero") + assert.Exactly(t, false, path.IsRegularFile(), "/dev/zero is file") + + //symlink test +} From 4c306c2ffedca807777e5c516e056195fda09647 Mon Sep 17 00:00:00 2001 From: Jan Seidl Date: Thu, 20 Apr 2017 14:49:15 +0200 Subject: [PATCH 07/54] test examples add open support add crypto support --- appveyor.yml | 2 +- crypto.go | 49 ++++++++++++++++++++++++++++++++++ crypto_test.go | 22 ++++++++++++++++ examples/example.json | 13 +++++++++ examples/json_test.go | 61 +++++++++++++++++++++++++++++++++++++++++++ open.go | 31 ++++++++++++++++++++++ 6 files changed, 177 insertions(+), 1 deletion(-) create mode 100644 crypto.go create mode 100644 crypto_test.go create mode 100644 examples/example.json create mode 100644 examples/json_test.go create mode 100644 open.go diff --git a/appveyor.yml b/appveyor.yml index 1a4a667..6ca1199 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -11,4 +11,4 @@ install: - go get -v -t build_script: - - go test -v + - go test -v ./... diff --git a/crypto.go b/crypto.go new file mode 100644 index 0000000..13a334e --- /dev/null +++ b/crypto.go @@ -0,0 +1,49 @@ +package path + +import ( + "crypto" + "fmt" + "hash" + "io" +) + +// Crypto method access hash funcionality like Path::Tiny Digest +// look to https://godoc.org/crypto#Hash for list possible crypto hash functions +// +// for example print of Sha256 hexstring +// hash, err := path.Crypto(crypto.SHA256) +// fmt.Println(hash.HexSum()) + +func (path *Path) Crypto(hash crypto.Hash) (*CryptoHash, error) { + reader, err := path.OpenReader() + if err != nil { + return nil, err + } + + h := hash.New() + + _, err = io.Copy(h, reader) + + if err != nil { + return nil, err + } + + return &CryptoHash{h}, nil +} + +// CryptoHash struct is only abstract for hash.Hash interface +// for possible use with methods + +type CryptoHash struct { + hash.Hash +} + +// BinSum method is like hash.Sum(nil) +func (hash *CryptoHash) BinSum() []byte { + return hash.Sum(nil) +} + +// HexSum method retun hexstring representation of hash.Sum +func (hash *CryptoHash) HexSum() string { + return fmt.Sprintf("%x", hash.Sum(nil)) +} diff --git a/crypto_test.go b/crypto_test.go new file mode 100644 index 0000000..72aef10 --- /dev/null +++ b/crypto_test.go @@ -0,0 +1,22 @@ +package path + +import ( + "crypto" + "github.com/stretchr/testify/assert" + "testing" +) + +const emptyFileSha256Hex = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + +var emptyFileSha256Bin = []uint8{0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c, 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55} + +func TestPathCrypto(t *testing.T) { + path, err := NewTempFile(TempFileOpt{}) + assert.Nil(t, err) + defer path.Remove() + + hash, err := path.Crypto(crypto.Hash(crypto.SHA256)) + + assert.Equal(t, emptyFileSha256Hex, hash.HexSum()) + assert.Equal(t, emptyFileSha256Bin, hash.BinSum()) +} diff --git a/examples/example.json b/examples/example.json new file mode 100644 index 0000000..1608849 --- /dev/null +++ b/examples/example.json @@ -0,0 +1,13 @@ +{ + "file_id": "01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b", + "sources": [ + { + "path": "c:\\tmp\\empty_file", + "size": 0 + }, + { + "path": "/tmp/empty_file", + "size": 0 + } + ] +} diff --git a/examples/json_test.go b/examples/json_test.go new file mode 100644 index 0000000..18f34eb --- /dev/null +++ b/examples/json_test.go @@ -0,0 +1,61 @@ +package path_test + +import ( + "encoding/json" + "github.com/jasei/path-go" + "github.com/stretchr/testify/assert" + "testing" +) + +type FileSource struct { + Path string `json:"path"` + Size int `json:"size"` +} + +type FileInfo struct { + FileId string `json:"file_id"` + Sources []FileSource `json:"sources"` +} + +var expected = FileInfo{ + FileId: "01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b", + Sources: []FileSource{ + FileSource{Path: "c:\\tmp\\empty_file", Size: 0}, + FileSource{Path: "/tmp/empty_file", Size: 0}, + }, +} + +func TestLoadJsonViaReader(t *testing.T) { + path, err := path.NewPath("example.json") + assert.Nil(t, err) + + reader, err := path.OpenReader() + defer func() { + assert.Nil(t, path.Close()) + }() + assert.Nil(t, err) + assert.NotNil(t, reader) + + decodedJson := new(FileInfo) + + err = json.NewDecoder(reader).Decode(decodedJson) + if !assert.Nil(t, err) { + t.Log(err) + } + + assert.Equal(t, &expected, decodedJson) +} + +func TestLoadJsonViaSlurp(t *testing.T) { + path, err := path.NewPath("example.json") + assert.Nil(t, err) + + jsonBytes, err := path.Slurp() + assert.Nil(t, err) + + decodedJson := new(FileInfo) + json.Unmarshal(jsonBytes, decodedJson) + + assert.Equal(t, &expected, decodedJson) + +} diff --git a/open.go b/open.go new file mode 100644 index 0000000..7455ec3 --- /dev/null +++ b/open.go @@ -0,0 +1,31 @@ +package path + +import ( + "bufio" + "io" + "io/ioutil" + "os" +) + +func (path *Path) OpenReader() (io.Reader, error) { + file, err := os.Open(path.String()) + if err != nil { + return nil, err + } + + path.file = file + + return bufio.NewReader(file), nil +} + +func (path *Path) Close() error { + if path.file == nil { + return nil + } + + return path.file.Close() +} + +func (path *Path) Slurp() ([]byte, error) { + return ioutil.ReadFile(path.String()) +} From abf2a2da46fbbfa49e424a7fa819e37e43124c0b Mon Sep 17 00:00:00 2001 From: Jan Seidl Date: Sat, 22 Apr 2017 00:42:44 +0200 Subject: [PATCH 08/54] visit proof of concept --- examples/recursive_sha256sum_test.go | 31 +++++++++++++++++++++++++++ visit.go | 32 ++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) create mode 100644 examples/recursive_sha256sum_test.go create mode 100644 visit.go diff --git a/examples/recursive_sha256sum_test.go b/examples/recursive_sha256sum_test.go new file mode 100644 index 0000000..efd44a9 --- /dev/null +++ b/examples/recursive_sha256sum_test.go @@ -0,0 +1,31 @@ +package path_test + +import ( + "crypto" + "fmt" + pathutils "github.com/jasei/path-go" + "github.com/stretchr/testify/assert" + "testing" +) + +func TestVisitRecursiveAndHashAllFiles(t *testing.T) { + path, err := pathutils.NewPath("/tmp") + assert.Nil(t, err) + + path.Visit( + func(path *pathutils.Path) { + if path.IsDir() { + return + } + + hash, err := path.Crypto(crypto.SHA256) + + if err == nil { + fmt.Printf("%s\t%s\n", hash.HexSum(), path.String()) + } else { + fmt.Println(err) + } + }, + pathutils.VisitOpt{Recurse: true}, + ) +} diff --git a/visit.go b/visit.go new file mode 100644 index 0000000..9640772 --- /dev/null +++ b/visit.go @@ -0,0 +1,32 @@ +package path + +import ( + "os" + "path/filepath" +) + +type VisitFunc func(path *Path) + +type VisitOpt struct { + Recurse bool +} + +func (path *Path) Visit(visitFunc VisitFunc, visitOpt VisitOpt) { + walkFn := func(file string, info os.FileInfo, err error) error { + if info != nil && info.IsDir() && file != path.String() && !visitOpt.Recurse { + return filepath.SkipDir + } + + if err != nil { + return err + } + + path, err := NewPath(file) + + visitFunc(path) + + return nil + } + + return filepath.Walk(path.String(), walkFn) +} From 3719f27f691684d0fa6b2e676c1dc4092fd868f1 Mon Sep 17 00:00:00 2001 From: Jan Seidl Date: Sat, 22 Apr 2017 00:52:41 +0200 Subject: [PATCH 09/54] path are stored in slash style --- constructor.go | 2 +- copy.go | 2 +- visit.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/constructor.go b/constructor.go index e4f7574..6d09901 100644 --- a/constructor.go +++ b/constructor.go @@ -14,7 +14,7 @@ import ( // func NewPath(path ...string) (*Path, error) { newPath := new(Path) - newPath.Path = filepath.Join(path...) + newPath.Path = filepath.ToSlash(filepath.Join(path...)) if len(newPath.Path) == 0 { return nil, errors.New("Paths requires defined, positive-lengths parts") diff --git a/copy.go b/copy.go index 24f13ce..c4b4d9f 100644 --- a/copy.go +++ b/copy.go @@ -24,7 +24,7 @@ func (path *Path) RemoveTree() error { } func (path *Path) String() string { - return filepath.Clean(path.Path) + return filepath.FromSlash(filepath.Clean(path.Path)) } func (path *Path) Basename() string { diff --git a/visit.go b/visit.go index 9640772..16d6324 100644 --- a/visit.go +++ b/visit.go @@ -28,5 +28,5 @@ func (path *Path) Visit(visitFunc VisitFunc, visitOpt VisitOpt) { return nil } - return filepath.Walk(path.String(), walkFn) + filepath.Walk(path.String(), walkFn) } From 4075c74da9f7019e0c53edd8ce4255eceda6eaf1 Mon Sep 17 00:00:00 2001 From: Jan Seidl Date: Sun, 23 Apr 2017 00:38:12 +0200 Subject: [PATCH 10/54] visit test --- examples/tree/4 | 0 examples/tree/a/1 | 0 examples/tree/a/b/2 | 0 examples/tree/c/3 | 0 visit.go | 5 +++++ visit_test.go | 51 +++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 56 insertions(+) create mode 100644 examples/tree/4 create mode 100644 examples/tree/a/1 create mode 100644 examples/tree/a/b/2 create mode 100644 examples/tree/c/3 create mode 100644 visit_test.go diff --git a/examples/tree/4 b/examples/tree/4 new file mode 100644 index 0000000..e69de29 diff --git a/examples/tree/a/1 b/examples/tree/a/1 new file mode 100644 index 0000000..e69de29 diff --git a/examples/tree/a/b/2 b/examples/tree/a/b/2 new file mode 100644 index 0000000..e69de29 diff --git a/examples/tree/c/3 b/examples/tree/c/3 new file mode 100644 index 0000000..e69de29 diff --git a/visit.go b/visit.go index 16d6324..efc94fd 100644 --- a/visit.go +++ b/visit.go @@ -21,6 +21,11 @@ func (path *Path) Visit(visitFunc VisitFunc, visitOpt VisitOpt) { return err } + //skip self path + if file == path.String() { + return nil + } + path, err := NewPath(file) visitFunc(path) diff --git a/visit_test.go b/visit_test.go new file mode 100644 index 0000000..6341795 --- /dev/null +++ b/visit_test.go @@ -0,0 +1,51 @@ +package path + +import ( + "github.com/stretchr/testify/assert" + "testing" +) + +func TestVisit(t *testing.T) { + path, err := NewPath("examples/tree") + + assert.Nil(t, err) + + t.Run("flat visit", func(t *testing.T) { + flat_expected := map[string]int{ + "examples/tree/4": 0, + } + + flat := make(map[string]int) + path.Visit( + func(path *Path) { + flat[path.String()] = 0 + }, + VisitOpt{}, + ) + + assert.Equal(t, flat_expected, flat, "flat files") + }) + + t.Run("flat recurse", func(t *testing.T) { + flat_expected := map[string]int{ + "examples/tree/a": 0, + "examples/tree/a/1": 0, + "examples/tree/a/b": 0, + "examples/tree/a/b/2": 0, + "examples/tree/c": 0, + "examples/tree/c/3": 0, + "examples/tree/4": 0, + } + + flat := make(map[string]int) + path.Visit( + func(path *Path) { + flat[path.String()] = 0 + }, + VisitOpt{Recurse: true}, + ) + + assert.Equal(t, flat_expected, flat, "flat files") + }) + +} From f1f3212007dd4fbccf04465cfd0b221ea43b8e8a Mon Sep 17 00:00:00 2001 From: Jan Seidl Date: Mon, 24 Apr 2017 11:59:42 +0200 Subject: [PATCH 11/54] add badges: - codecov - sourcegraph --- .travis.yml | 9 +++++++++ README.md | 2 ++ test.sh | 12 ++++++++++++ 3 files changed, 23 insertions(+) create mode 100755 test.sh diff --git a/.travis.yml b/.travis.yml index 69d2f6d..804c663 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,3 +5,12 @@ go: - 1.6 - 1.7.x - master + +before_install: + - go get -t -v ./... + +script: + - ./test.sh + +after_success: + - bash <(curl -s https://codecov.io/bash) diff --git a/README.md b/README.md index de6eda5..6b74bf0 100644 --- a/README.md +++ b/README.md @@ -4,5 +4,7 @@ [![Build status](https://ci.appveyor.com/api/projects/status/urj0cf370sr5hjw4?svg=true)](https://ci.appveyor.com/project/JaSei/path-go) [![Go Report Card](https://goreportcard.com/badge/github.com/JaSei/path-go)](https://goreportcard.com/report/github.com/JaSei/path-go) [![GoDoc](https://godoc.org/github.com/JaSei/path-go?status.svg)](http://godoc.org/github.com/jasei/path-go) +[![Sourcegraph](https://sourcegraph.com/github.com/jasei/path-go/-/badge.svg)](https://sourcegraph.com/github.com/jasei/path-go?badge) +[![codecov.io](https://codecov.io/github/boennemann/badges/coverage.svg?branch=master)](https://codecov.io/github/jasei/path-go?branch=implementation) File path utility inspired by David Golden's [Path::Tiny](https://metacpan.org/pod/Path::Tiny) diff --git a/test.sh b/test.sh new file mode 100755 index 0000000..34dbbfb --- /dev/null +++ b/test.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash + +set -e +echo "" > coverage.txt + +for d in $(go list ./... | grep -v vendor); do + go test -race -coverprofile=profile.out -covermode=atomic $d + if [ -f profile.out ]; then + cat profile.out >> coverage.txt + rm profile.out + fi +done From 251123d7ecd17a8c20085844ff82b5f71a20d3cd Mon Sep 17 00:00:00 2001 From: Jan Seidl Date: Mon, 24 Apr 2017 12:13:26 +0200 Subject: [PATCH 12/54] fix travis build --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 804c663..0f712af 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,7 +7,7 @@ go: - master before_install: - - go get -t -v ./... + - go get -t -v script: - ./test.sh From 0099fdcecb84d09b691d2a7a3e05faf5109a6e12 Mon Sep 17 00:00:00 2001 From: Jan Seidl Date: Mon, 24 Apr 2017 22:29:29 +0200 Subject: [PATCH 13/54] fix travis build --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 0f712af..7384490 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,7 +6,7 @@ go: - 1.7.x - master -before_install: +install: - go get -t -v script: From cc3fd5438634cfc35e04359166dc340856ed8f43 Mon Sep 17 00:00:00 2001 From: Jan Seidl Date: Mon, 24 Apr 2017 22:55:19 +0200 Subject: [PATCH 14/54] fix travis test --- .travis.yml | 12 ++++++++---- examples/json_test.go | 2 +- examples/recursive_sha256sum_test.go | 2 +- test.sh | 2 +- 4 files changed, 11 insertions(+), 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index 7384490..b21cf81 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,13 +1,17 @@ language: go go: - - 1.x + - 1.1 + - 1.2 + - 1.3 + - 1.4 + - 1.5 - 1.6 - - 1.7.x - - master + - 1.7 + - tip install: - - go get -t -v + - go get -t -v ./... script: - ./test.sh diff --git a/examples/json_test.go b/examples/json_test.go index 18f34eb..54a69f1 100644 --- a/examples/json_test.go +++ b/examples/json_test.go @@ -2,7 +2,7 @@ package path_test import ( "encoding/json" - "github.com/jasei/path-go" + "github.com/JaSei/path-go" "github.com/stretchr/testify/assert" "testing" ) diff --git a/examples/recursive_sha256sum_test.go b/examples/recursive_sha256sum_test.go index efd44a9..6b80842 100644 --- a/examples/recursive_sha256sum_test.go +++ b/examples/recursive_sha256sum_test.go @@ -3,7 +3,7 @@ package path_test import ( "crypto" "fmt" - pathutils "github.com/jasei/path-go" + pathutils "github.com/JaSei/path-go" "github.com/stretchr/testify/assert" "testing" ) diff --git a/test.sh b/test.sh index 34dbbfb..88c4e8b 100755 --- a/test.sh +++ b/test.sh @@ -4,7 +4,7 @@ set -e echo "" > coverage.txt for d in $(go list ./... | grep -v vendor); do - go test -race -coverprofile=profile.out -covermode=atomic $d + go test -v -race -coverprofile=profile.out -covermode=atomic $d if [ -f profile.out ]; then cat profile.out >> coverage.txt rm profile.out From 610a1585ed40f9547a97be23b9aed926df9f5364 Mon Sep 17 00:00:00 2001 From: Jan Seidl Date: Mon, 24 Apr 2017 22:59:07 +0200 Subject: [PATCH 15/54] ignore `no buildable Go source files` --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index b21cf81..117f79a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,7 +11,7 @@ go: - tip install: - - go get -t -v ./... + - go get -t -v -d ./... script: - ./test.sh From 7f24156bd6ff2a884095ccb8067527cfec80cde7 Mon Sep 17 00:00:00 2001 From: Jan Seidl Date: Mon, 24 Apr 2017 23:12:43 +0200 Subject: [PATCH 16/54] don't test with go 1.1 --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 117f79a..2e51911 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,6 @@ language: go go: - - 1.1 - 1.2 - 1.3 - 1.4 From 40d7e6fabbb0632c7181a40fb4a9662ab30bb0ad Mon Sep 17 00:00:00 2001 From: Jan Seidl Date: Mon, 24 Apr 2017 23:16:57 +0200 Subject: [PATCH 17/54] remove testing.Run, becuase is only in go 1.7+ --- copy_test.go | 107 ++++++++++++++++++++++++-------------------------- visit_test.go | 77 ++++++++++++++++++------------------ 2 files changed, 90 insertions(+), 94 deletions(-) diff --git a/copy_test.go b/copy_test.go index 7e9e247..cb9fa5b 100644 --- a/copy_test.go +++ b/copy_test.go @@ -40,60 +40,55 @@ func TestTempFile(t *testing.T) { assert.Exactly(t, true, temp.Exists(), "new temp file exists") } -func TestCopyFile(t *testing.T) { - t.Run("dst file not exists", - func(t *testing.T) { - src, err := NewPath("copy_test.go") - assert.Nil(t, err) - - dst, err := NewTempFile(TempFileOpt{}) - assert.Nil(t, err) - defer dst.Remove() - dst.Remove() - - assert.Exactly(t, false, dst.Exists(), "dst file isn't exists") - newDst, err := src.CopyFile(dst.String()) - assert.Nil(t, err) - if err != nil { - t.Log(err) - } else { - assert.Equal(t, dst.String(), newDst.String(), "dst file is same as what return CopyFile") - assert.Exactly(t, true, newDst.Exists(), "dst file after copy exists") - } - }) - - t.Run("dst file exists", - func(t *testing.T) { - src, _ := NewPath("copy_test.go") - dst, err := NewTempFile(TempFileOpt{}) - assert.Nil(t, err) - defer dst.Remove() - - assert.Exactly(t, true, dst.Exists(), "dst file exists before copy") - newDst, err := src.CopyFile(dst.String()) - if !assert.Nil(t, err) { - return - } - - assert.Equal(t, dst.String(), newDst.String(), "dst file is same as what return CopyFile") - assert.Exactly(t, true, newDst.Exists(), "dst file after copy exists") - }) - - t.Run("dst is dir", - func(t *testing.T) { - src, _ := NewPath("copy_test.go") - dst, _ := NewPath(os.TempDir()) - - assert.Exactly(t, true, dst.Exists(), "dst dir exists") - newDst, err := src.CopyFile(dst.String()) - if !assert.Nil(t, err) { - return - } - - defer newDst.Remove() - - assert.Exactly(t, true, newDst.Exists(), "dst after copy exists") - assert.Exactly(t, true, newDst.IsFile(), "dst is file") - assert.Equal(t, src.Basename(), newDst.Basename(), "if is dst directory, then is used basename of source") - }) +func TestCopyFileDstFileNotExists(t *testing.T) { + src, err := NewPath("copy_test.go") + assert.Nil(t, err) + + dst, err := NewTempFile(TempFileOpt{}) + assert.Nil(t, err) + defer dst.Remove() + dst.Remove() + + assert.Exactly(t, false, dst.Exists(), "dst file isn't exists") + newDst, err := src.CopyFile(dst.String()) + assert.Nil(t, err) + if err != nil { + t.Log(err) + } else { + assert.Equal(t, dst.String(), newDst.String(), "dst file is same as what return CopyFile") + assert.Exactly(t, true, newDst.Exists(), "dst file after copy exists") + } +} + +func TestCopyFileDstFileExists(t *testing.T) { + src, _ := NewPath("copy_test.go") + dst, err := NewTempFile(TempFileOpt{}) + assert.Nil(t, err) + defer dst.Remove() + + assert.Exactly(t, true, dst.Exists(), "dst file exists before copy") + newDst, err := src.CopyFile(dst.String()) + if !assert.Nil(t, err) { + return + } + + assert.Equal(t, dst.String(), newDst.String(), "dst file is same as what return CopyFile") + assert.Exactly(t, true, newDst.Exists(), "dst file after copy exists") +} + +func TestCopyFileDstIsDir(t *testing.T) { + src, _ := NewPath("copy_test.go") + dst, _ := NewPath(os.TempDir()) + + assert.Exactly(t, true, dst.Exists(), "dst dir exists") + newDst, err := src.CopyFile(dst.String()) + if !assert.Nil(t, err) { + return + } + + defer newDst.Remove() + + assert.Exactly(t, true, newDst.Exists(), "dst after copy exists") + assert.Exactly(t, true, newDst.IsFile(), "dst is file") + assert.Equal(t, src.Basename(), newDst.Basename(), "if is dst directory, then is used basename of source") } diff --git a/visit_test.go b/visit_test.go index 6341795..a3faf1a 100644 --- a/visit_test.go +++ b/visit_test.go @@ -5,47 +5,48 @@ import ( "testing" ) -func TestVisit(t *testing.T) { +func TestVisitFlat(t *testing.T) { + path, err := NewPath("examples/tree") + + assert.Nil(t, err) + flat_expected := map[string]int{ + "examples/tree/4": 0, + } + + flat := make(map[string]int) + path.Visit( + func(path *Path) { + flat[path.String()] = 0 + }, + VisitOpt{}, + ) + + assert.Equal(t, flat_expected, flat, "flat files") +} + +func TestVisitRecurse(t *testing.T) { path, err := NewPath("examples/tree") assert.Nil(t, err) - t.Run("flat visit", func(t *testing.T) { - flat_expected := map[string]int{ - "examples/tree/4": 0, - } - - flat := make(map[string]int) - path.Visit( - func(path *Path) { - flat[path.String()] = 0 - }, - VisitOpt{}, - ) - - assert.Equal(t, flat_expected, flat, "flat files") - }) - - t.Run("flat recurse", func(t *testing.T) { - flat_expected := map[string]int{ - "examples/tree/a": 0, - "examples/tree/a/1": 0, - "examples/tree/a/b": 0, - "examples/tree/a/b/2": 0, - "examples/tree/c": 0, - "examples/tree/c/3": 0, - "examples/tree/4": 0, - } - - flat := make(map[string]int) - path.Visit( - func(path *Path) { - flat[path.String()] = 0 - }, - VisitOpt{Recurse: true}, - ) - - assert.Equal(t, flat_expected, flat, "flat files") - }) + flat_expected := map[string]int{ + "examples/tree/a": 0, + "examples/tree/a/1": 0, + "examples/tree/a/b": 0, + "examples/tree/a/b/2": 0, + "examples/tree/c": 0, + "examples/tree/c/3": 0, + "examples/tree/4": 0, + } + + flat := make(map[string]int) + path.Visit( + func(path *Path) { + flat[path.String()] = 0 + }, + VisitOpt{Recurse: true}, + ) + + assert.Equal(t, flat_expected, flat, "flat files") } From 835489a14481e3a9a3754d06f087fc1143252aea Mon Sep 17 00:00:00 2001 From: Jan Seidl Date: Thu, 27 Apr 2017 10:41:01 +0200 Subject: [PATCH 18/54] fix some windows problems (maybe) separate base method to base.go file --- base.go | 43 ++++++++++++++++++++++++++++++++++ base_test.go | 47 +++++++++++++++++++++++++++++++++++++ constructor.go | 3 ++- constructor_test.go | 9 ++++++++ copy.go | 30 ------------------------ copy_test.go | 54 ------------------------------------------- crypto.go | 3 ++- examples/json_test.go | 6 ++--- open.go | 26 ++++++++++++--------- stat_test.go | 10 ++++---- 10 files changed, 126 insertions(+), 105 deletions(-) create mode 100644 base.go create mode 100644 base_test.go diff --git a/base.go b/base.go new file mode 100644 index 0000000..499ff20 --- /dev/null +++ b/base.go @@ -0,0 +1,43 @@ +package path + +import ( + "os" + "path/filepath" +) + +// Remove file +// err := path.Remove() +// like os.Remove + +func (path *Path) Remove() error { + path.file = nil + return os.Remove(path.Path) +} + +// Remove tree of files +// err := path.RemoveTree +// like os.RemoveAll +func (path *Path) RemoveTree() error { + path.file = nil + return os.RemoveAll(path.Path) +} + +// String return stable string representation of path +// this representation is linux like (slash as separator) +// for os specific string use Canonpath method +func (path *Path) String() string { + return filepath.Clean(path.Path) +} + +// Canonpath retrun path with right os separator +func (path *Path) Canonpath() string { + return filepath.FromSlash(filepath.Clean(path.Path)) +} + +func (path *Path) Basename() string { + if path.Path == "/" { + return "" + } + + return filepath.Base(path.Path) +} diff --git a/base_test.go b/base_test.go new file mode 100644 index 0000000..7f188c2 --- /dev/null +++ b/base_test.go @@ -0,0 +1,47 @@ +package path + +import ( + "fmt" + "github.com/stretchr/testify/assert" + "path/filepath" + "testing" +) + +func TestString(t *testing.T) { + path, _ := NewPath("tmp/test") + assert.Equal(t, "tmp/test", path.String(), "string") + + path, _ = NewPath("tmp/test/") + assert.Equal(t, "tmp/test", path.String(), "string") + + path, _ = NewPath("tmp", "test") + assert.Equal(t, "tmp/test", path.String(), "string") +} + +func TestCanonpath(t *testing.T) { + path, _ := NewPath("tmp/test") + assert.Equal(t, fmt.Sprintf("tmp%stest", string(filepath.Separator)), path.Canonpath(), "linux rel path") + + path, _ = NewPath("tmp/test/") + assert.Equal(t, fmt.Sprintf("tmp%stest", string(filepath.Separator)), path.Canonpath(), "linux rel path with end slash") + + path, _ = NewPath("tmp", "test") + assert.Equal(t, fmt.Sprintf("tmp%stest", string(filepath.Separator)), path.Canonpath(), "more paths elemets") + + path, _ = NewPath("tmp\\test") + assert.Equal(t, fmt.Sprintf("tmp%stest", string(filepath.Separator)), path.Canonpath(), "windows rel path") +} + +func TestBasename(t *testing.T) { + path, _ := NewPath("/tmp/test") + assert.Equal(t, "test", path.Basename(), "basename of /tmp/test") + + path, _ = NewPath("/") + assert.Equal(t, "", path.Basename(), "basename of root") + + path, _ = NewPath("relative") + assert.Equal(t, "relative", path.Basename(), "relative basename") + + path, _ = NewPath("relative/a") + assert.Equal(t, "a", path.Basename(), "relative subpath basename") +} diff --git a/constructor.go b/constructor.go index 6d09901..0df4996 100644 --- a/constructor.go +++ b/constructor.go @@ -5,6 +5,7 @@ import ( "io/ioutil" "os" "path/filepath" + "strings" ) // NewPath construct *Path @@ -14,7 +15,7 @@ import ( // func NewPath(path ...string) (*Path, error) { newPath := new(Path) - newPath.Path = filepath.ToSlash(filepath.Join(path...)) + newPath.Path = strings.Replace(filepath.Join(path...), "\\", "/", -1) if len(newPath.Path) == 0 { return nil, errors.New("Paths requires defined, positive-lengths parts") diff --git a/constructor_test.go b/constructor_test.go index 5e91d46..eb1fcea 100644 --- a/constructor_test.go +++ b/constructor_test.go @@ -26,3 +26,12 @@ func TestNewTempFile(t *testing.T) { assert.NotNil(t, temp) assert.Nil(t, err) } + +func TestTempFile(t *testing.T) { + temp, err := NewTempFile(TempFileOpt{Prefix: "bla"}) + defer temp.Remove() + + assert.NotNil(t, temp) + assert.Nil(t, err) + assert.Exactly(t, true, temp.Exists(), "new temp file exists") +} diff --git a/copy.go b/copy.go index c4b4d9f..a3b5854 100644 --- a/copy.go +++ b/copy.go @@ -3,38 +3,8 @@ package path import ( "io" "os" - "path/filepath" ) -// Remove file -// err := path.Remove() -// like os.Remove - -func (path *Path) Remove() error { - path.file = nil - return os.Remove(path.Path) -} - -// Remove tree of files -// err := path.RemoveTree -// like os.RemoveAll -func (path *Path) RemoveTree() error { - path.file = nil - return os.RemoveAll(path.Path) -} - -func (path *Path) String() string { - return filepath.FromSlash(filepath.Clean(path.Path)) -} - -func (path *Path) Basename() string { - if path.Path == "/" { - return "" - } - - return filepath.Base(path.Path) -} - func (srcPath *Path) CopyFile(dst string) (*Path, error) { dstPath, err := NewPath(dst) if err != nil { diff --git a/copy_test.go b/copy_test.go index cb9fa5b..48aa24b 100644 --- a/copy_test.go +++ b/copy_test.go @@ -6,60 +6,6 @@ import ( "testing" ) -func TestString(t *testing.T) { - path, _ := NewPath("/tmp/test") - assert.Equal(t, "/tmp/test", path.String(), "string") - - path, _ = NewPath("/tmp/test/") - assert.Equal(t, "/tmp/test", path.String(), "string") - - path, _ = NewPath("/tmp", "test") - assert.Equal(t, "/tmp/test", path.String(), "string") -} - -func TestBasename(t *testing.T) { - path, _ := NewPath("/tmp/test") - assert.Equal(t, "test", path.Basename(), "basename of /tmp/test") - - path, _ = NewPath("/") - assert.Equal(t, "", path.Basename(), "basename of root") - - path, _ = NewPath("relative") - assert.Equal(t, "relative", path.Basename(), "relative basename") - - path, _ = NewPath("relative/a") - assert.Equal(t, "a", path.Basename(), "relative subpath basename") -} - -func TestTempFile(t *testing.T) { - temp, err := NewTempFile(TempFileOpt{Prefix: "bla"}) - defer temp.Remove() - - assert.NotNil(t, temp) - assert.Nil(t, err) - assert.Exactly(t, true, temp.Exists(), "new temp file exists") -} - -func TestCopyFileDstFileNotExists(t *testing.T) { - src, err := NewPath("copy_test.go") - assert.Nil(t, err) - - dst, err := NewTempFile(TempFileOpt{}) - assert.Nil(t, err) - defer dst.Remove() - dst.Remove() - - assert.Exactly(t, false, dst.Exists(), "dst file isn't exists") - newDst, err := src.CopyFile(dst.String()) - assert.Nil(t, err) - if err != nil { - t.Log(err) - } else { - assert.Equal(t, dst.String(), newDst.String(), "dst file is same as what return CopyFile") - assert.Exactly(t, true, newDst.Exists(), "dst file after copy exists") - } -} - func TestCopyFileDstFileExists(t *testing.T) { src, _ := NewPath("copy_test.go") dst, err := NewTempFile(TempFileOpt{}) diff --git a/crypto.go b/crypto.go index 13a334e..18050e9 100644 --- a/crypto.go +++ b/crypto.go @@ -15,10 +15,11 @@ import ( // fmt.Println(hash.HexSum()) func (path *Path) Crypto(hash crypto.Hash) (*CryptoHash, error) { - reader, err := path.OpenReader() + reader, file, err := path.OpenReader() if err != nil { return nil, err } + defer file.Close() h := hash.New() diff --git a/examples/json_test.go b/examples/json_test.go index 54a69f1..5b5fa67 100644 --- a/examples/json_test.go +++ b/examples/json_test.go @@ -29,11 +29,11 @@ func TestLoadJsonViaReader(t *testing.T) { path, err := path.NewPath("example.json") assert.Nil(t, err) - reader, err := path.OpenReader() + reader, file, err := path.OpenReader() + assert.Nil(t, err) defer func() { - assert.Nil(t, path.Close()) + assert.Nil(t, file.Close()) }() - assert.Nil(t, err) assert.NotNil(t, reader) decodedJson := new(FileInfo) diff --git a/open.go b/open.go index 7455ec3..59d7bbe 100644 --- a/open.go +++ b/open.go @@ -7,23 +7,27 @@ import ( "os" ) -func (path *Path) OpenReader() (io.Reader, error) { +// OpenReader retun bufio io.Reader +// because bufio io.Reader don't implement Close method, +// OpenReader returns *os.File too +// +// for example: +// path, _ := NewPath("/bla/bla") +// reader, file, err := path.OpenReader() +// if err != nil { +// panic(err) +// } +// defer file.Close() + +func (path *Path) OpenReader() (io.Reader, *os.File, error) { file, err := os.Open(path.String()) if err != nil { - return nil, err + return nil, nil, err } path.file = file - return bufio.NewReader(file), nil -} - -func (path *Path) Close() error { - if path.file == nil { - return nil - } - - return path.file.Close() + return bufio.NewReader(file), file, nil } func (path *Path) Slurp() ([]byte, error) { diff --git a/stat_test.go b/stat_test.go index 84f7d5a..60e2198 100644 --- a/stat_test.go +++ b/stat_test.go @@ -7,8 +7,8 @@ import ( ) func TestExists(t *testing.T) { - path, _ := NewPath("copy_test.go") - assert.Exactly(t, true, path.Exists(), "this test exists") + path, _ := NewPath("stat_test.go") + assert.Exactly(t, true, path.Exists(), "file exists") path, _ = NewPath("/sdlkfjsflsjfsl") assert.Exactly(t, false, path.Exists(), "wired root dir don't exists") path, _ = NewPath(os.TempDir()) @@ -19,7 +19,7 @@ func TestIsDir(t *testing.T) { path, _ := NewPath(os.TempDir()) assert.Exactly(t, true, path.IsDir(), "temp dir is dir") - path, _ = NewPath("copy_test.go") + path, _ = NewPath("stat_test.go") assert.Exactly(t, false, path.IsDir(), "this test file isn't dir") path, _ = NewPath("/safjasfjalfja") @@ -30,7 +30,7 @@ func TestIsFile(t *testing.T) { path, _ := NewPath(os.TempDir()) assert.Exactly(t, false, path.IsFile(), "temp dir is dir - no file") - path, _ = NewPath("copy_test.go") + path, _ = NewPath("stat_test.go") assert.Exactly(t, true, path.IsFile(), "this test file is file") path, _ = NewPath("/safjasfjalfja") @@ -46,7 +46,7 @@ func TestIsRegularFile(t *testing.T) { path, _ := NewPath(os.TempDir()) assert.Exactly(t, false, path.IsRegularFile(), "temp dir is dir - no file") - path, _ = NewPath("copy_test.go") + path, _ = NewPath("stat_test.go") assert.Exactly(t, true, path.IsRegularFile(), "this test file is file") path, _ = NewPath("/safjasfjalfja") From 0618c87ec49cf046d11b597b68785c41c8c134c1 Mon Sep 17 00:00:00 2001 From: Jan Seidl Date: Thu, 27 Apr 2017 19:10:56 +0200 Subject: [PATCH 19/54] rename package from path (which is core module too) to utilpath --- base.go | 5 +++-- base_test.go | 2 +- constructor.go | 2 +- constructor_test.go | 2 +- copy.go | 2 +- copy_test.go | 2 +- crypto.go | 2 +- crypto_test.go | 2 +- examples/json_test.go | 8 ++++---- examples/recursive_sha256sum_test.go | 10 +++++----- open.go | 6 ++++-- stat.go | 2 +- stat_test.go | 8 ++++---- struct.go | 2 +- visit.go | 2 +- visit_test.go | 2 +- 16 files changed, 31 insertions(+), 28 deletions(-) diff --git a/base.go b/base.go index 499ff20..edc8053 100644 --- a/base.go +++ b/base.go @@ -1,4 +1,4 @@ -package path +package utilpath import ( "os" @@ -8,7 +8,6 @@ import ( // Remove file // err := path.Remove() // like os.Remove - func (path *Path) Remove() error { path.file = nil return os.Remove(path.Path) @@ -34,6 +33,8 @@ func (path *Path) Canonpath() string { return filepath.FromSlash(filepath.Clean(path.Path)) } +// Basename +// like path/filepath.Base func (path *Path) Basename() string { if path.Path == "/" { return "" diff --git a/base_test.go b/base_test.go index 7f188c2..b5a1e47 100644 --- a/base_test.go +++ b/base_test.go @@ -1,4 +1,4 @@ -package path +package utilpath import ( "fmt" diff --git a/constructor.go b/constructor.go index 0df4996..3407319 100644 --- a/constructor.go +++ b/constructor.go @@ -1,4 +1,4 @@ -package path +package utilpath import ( "errors" diff --git a/constructor_test.go b/constructor_test.go index eb1fcea..4a0970e 100644 --- a/constructor_test.go +++ b/constructor_test.go @@ -1,4 +1,4 @@ -package path +package utilpath import ( "github.com/stretchr/testify/assert" diff --git a/copy.go b/copy.go index a3b5854..542d389 100644 --- a/copy.go +++ b/copy.go @@ -1,4 +1,4 @@ -package path +package utilpath import ( "io" diff --git a/copy_test.go b/copy_test.go index 48aa24b..498858a 100644 --- a/copy_test.go +++ b/copy_test.go @@ -1,4 +1,4 @@ -package path +package utilpath import ( "github.com/stretchr/testify/assert" diff --git a/crypto.go b/crypto.go index 18050e9..8780504 100644 --- a/crypto.go +++ b/crypto.go @@ -1,4 +1,4 @@ -package path +package utilpath import ( "crypto" diff --git a/crypto_test.go b/crypto_test.go index 72aef10..031d322 100644 --- a/crypto_test.go +++ b/crypto_test.go @@ -1,4 +1,4 @@ -package path +package utilpath import ( "crypto" diff --git a/examples/json_test.go b/examples/json_test.go index 5b5fa67..464518d 100644 --- a/examples/json_test.go +++ b/examples/json_test.go @@ -1,8 +1,8 @@ -package path_test +package utilpath_test import ( "encoding/json" - "github.com/JaSei/path-go" + "github.com/JaSei/utilpath" "github.com/stretchr/testify/assert" "testing" ) @@ -26,7 +26,7 @@ var expected = FileInfo{ } func TestLoadJsonViaReader(t *testing.T) { - path, err := path.NewPath("example.json") + path, err := utilpath.NewPath("example.json") assert.Nil(t, err) reader, file, err := path.OpenReader() @@ -47,7 +47,7 @@ func TestLoadJsonViaReader(t *testing.T) { } func TestLoadJsonViaSlurp(t *testing.T) { - path, err := path.NewPath("example.json") + path, err := utilpath.NewPath("example.json") assert.Nil(t, err) jsonBytes, err := path.Slurp() diff --git a/examples/recursive_sha256sum_test.go b/examples/recursive_sha256sum_test.go index 6b80842..fb038e8 100644 --- a/examples/recursive_sha256sum_test.go +++ b/examples/recursive_sha256sum_test.go @@ -1,19 +1,19 @@ -package path_test +package utilpath_test import ( "crypto" "fmt" - pathutils "github.com/JaSei/path-go" + "github.com/JaSei/utilpath" "github.com/stretchr/testify/assert" "testing" ) func TestVisitRecursiveAndHashAllFiles(t *testing.T) { - path, err := pathutils.NewPath("/tmp") + path, err := utilpath.NewPath("/tmp") assert.Nil(t, err) path.Visit( - func(path *pathutils.Path) { + func(path *utilpath.Path) { if path.IsDir() { return } @@ -26,6 +26,6 @@ func TestVisitRecursiveAndHashAllFiles(t *testing.T) { fmt.Println(err) } }, - pathutils.VisitOpt{Recurse: true}, + utilpath.VisitOpt{Recurse: true}, ) } diff --git a/open.go b/open.go index 59d7bbe..2b96b62 100644 --- a/open.go +++ b/open.go @@ -1,4 +1,4 @@ -package path +package utilpath import ( "bufio" @@ -18,7 +18,7 @@ import ( // panic(err) // } // defer file.Close() - +// func (path *Path) OpenReader() (io.Reader, *os.File, error) { file, err := os.Open(path.String()) if err != nil { @@ -30,6 +30,8 @@ func (path *Path) OpenReader() (io.Reader, *os.File, error) { return bufio.NewReader(file), file, nil } +// Slurp read all file +// like ioutil.ReadFile func (path *Path) Slurp() ([]byte, error) { return ioutil.ReadFile(path.String()) } diff --git a/stat.go b/stat.go index 999577e..18ddcbc 100644 --- a/stat.go +++ b/stat.go @@ -1,4 +1,4 @@ -package path +package utilpath import ( "fmt" diff --git a/stat_test.go b/stat_test.go index 60e2198..45b79f1 100644 --- a/stat_test.go +++ b/stat_test.go @@ -1,4 +1,4 @@ -package path +package utilpath import ( "github.com/stretchr/testify/assert" @@ -34,7 +34,7 @@ func TestIsFile(t *testing.T) { assert.Exactly(t, true, path.IsFile(), "this test file is file") path, _ = NewPath("/safjasfjalfja") - assert.Exactly(t, false, path.IsFile(), "unexists somethings isn't file") + assert.Exactly(t, false, path.IsFile(), "unexists something isn't file") path, _ = NewPath("/dev/zero") assert.Exactly(t, true, path.IsFile(), "/dev/zero is file") @@ -50,10 +50,10 @@ func TestIsRegularFile(t *testing.T) { assert.Exactly(t, true, path.IsRegularFile(), "this test file is file") path, _ = NewPath("/safjasfjalfja") - assert.Exactly(t, false, path.IsRegularFile(), "unexists somethings isn't file") + assert.Exactly(t, false, path.IsRegularFile(), "unexists something isn't file") path, _ = NewPath("/dev/zero") - assert.Exactly(t, false, path.IsRegularFile(), "/dev/zero is file") + assert.Exactly(t, false, path.IsRegularFile(), "/dev/zero isn't regular file file") //symlink test } diff --git a/struct.go b/struct.go index 7215cd2..df310ee 100644 --- a/struct.go +++ b/struct.go @@ -1,4 +1,4 @@ -package path +package utilpath import ( "os" diff --git a/visit.go b/visit.go index efc94fd..0ee61b7 100644 --- a/visit.go +++ b/visit.go @@ -1,4 +1,4 @@ -package path +package utilpath import ( "os" diff --git a/visit_test.go b/visit_test.go index a3faf1a..2dc4f43 100644 --- a/visit_test.go +++ b/visit_test.go @@ -1,4 +1,4 @@ -package path +package utilpath import ( "github.com/stretchr/testify/assert" From cc0f63d046cefe949e3683fa6e1331c8a561c54c Mon Sep 17 00:00:00 2001 From: Jan Seidl Date: Sat, 29 Apr 2017 23:30:47 +0200 Subject: [PATCH 20/54] rename to utilpath --- base.go | 2 +- base_test.go | 2 +- constructor.go | 2 +- constructor_test.go | 2 +- copy.go | 2 +- copy_test.go | 2 +- crypto.go | 2 +- crypto_test.go | 2 +- examples/json_test.go | 8 ++++---- examples/recursive_sha256sum_test.go | 10 +++++----- open.go | 2 +- stat.go | 2 +- stat_test.go | 2 +- struct.go | 2 +- visit.go | 2 +- visit_test.go | 2 +- 16 files changed, 23 insertions(+), 23 deletions(-) diff --git a/base.go b/base.go index edc8053..d6c3165 100644 --- a/base.go +++ b/base.go @@ -1,4 +1,4 @@ -package utilpath +package pathutil import ( "os" diff --git a/base_test.go b/base_test.go index b5a1e47..8f62c57 100644 --- a/base_test.go +++ b/base_test.go @@ -1,4 +1,4 @@ -package utilpath +package pathutil import ( "fmt" diff --git a/constructor.go b/constructor.go index 3407319..fcc90e2 100644 --- a/constructor.go +++ b/constructor.go @@ -1,4 +1,4 @@ -package utilpath +package pathutil import ( "errors" diff --git a/constructor_test.go b/constructor_test.go index 4a0970e..134f568 100644 --- a/constructor_test.go +++ b/constructor_test.go @@ -1,4 +1,4 @@ -package utilpath +package pathutil import ( "github.com/stretchr/testify/assert" diff --git a/copy.go b/copy.go index 542d389..2f746f6 100644 --- a/copy.go +++ b/copy.go @@ -1,4 +1,4 @@ -package utilpath +package pathutil import ( "io" diff --git a/copy_test.go b/copy_test.go index 498858a..0a655ad 100644 --- a/copy_test.go +++ b/copy_test.go @@ -1,4 +1,4 @@ -package utilpath +package pathutil import ( "github.com/stretchr/testify/assert" diff --git a/crypto.go b/crypto.go index 8780504..c6ccdec 100644 --- a/crypto.go +++ b/crypto.go @@ -1,4 +1,4 @@ -package utilpath +package pathutil import ( "crypto" diff --git a/crypto_test.go b/crypto_test.go index 031d322..8aff056 100644 --- a/crypto_test.go +++ b/crypto_test.go @@ -1,4 +1,4 @@ -package utilpath +package pathutil import ( "crypto" diff --git a/examples/json_test.go b/examples/json_test.go index 464518d..7bae86f 100644 --- a/examples/json_test.go +++ b/examples/json_test.go @@ -1,8 +1,8 @@ -package utilpath_test +package pathutil_test import ( "encoding/json" - "github.com/JaSei/utilpath" + "github.com/JaSei/pathutil" "github.com/stretchr/testify/assert" "testing" ) @@ -26,7 +26,7 @@ var expected = FileInfo{ } func TestLoadJsonViaReader(t *testing.T) { - path, err := utilpath.NewPath("example.json") + path, err := pathutil.NewPath("example.json") assert.Nil(t, err) reader, file, err := path.OpenReader() @@ -47,7 +47,7 @@ func TestLoadJsonViaReader(t *testing.T) { } func TestLoadJsonViaSlurp(t *testing.T) { - path, err := utilpath.NewPath("example.json") + path, err := pathutil.NewPath("example.json") assert.Nil(t, err) jsonBytes, err := path.Slurp() diff --git a/examples/recursive_sha256sum_test.go b/examples/recursive_sha256sum_test.go index fb038e8..ac869fb 100644 --- a/examples/recursive_sha256sum_test.go +++ b/examples/recursive_sha256sum_test.go @@ -1,19 +1,19 @@ -package utilpath_test +package pathutil_test import ( "crypto" "fmt" - "github.com/JaSei/utilpath" + "github.com/JaSei/pathutil" "github.com/stretchr/testify/assert" "testing" ) func TestVisitRecursiveAndHashAllFiles(t *testing.T) { - path, err := utilpath.NewPath("/tmp") + path, err := pathutil.NewPath("/tmp") assert.Nil(t, err) path.Visit( - func(path *utilpath.Path) { + func(path *pathutil.Path) { if path.IsDir() { return } @@ -26,6 +26,6 @@ func TestVisitRecursiveAndHashAllFiles(t *testing.T) { fmt.Println(err) } }, - utilpath.VisitOpt{Recurse: true}, + pathutil.VisitOpt{Recurse: true}, ) } diff --git a/open.go b/open.go index 2b96b62..2679b77 100644 --- a/open.go +++ b/open.go @@ -1,4 +1,4 @@ -package utilpath +package pathutil import ( "bufio" diff --git a/stat.go b/stat.go index 18ddcbc..e1d0b1e 100644 --- a/stat.go +++ b/stat.go @@ -1,4 +1,4 @@ -package utilpath +package pathutil import ( "fmt" diff --git a/stat_test.go b/stat_test.go index 45b79f1..95b3cc1 100644 --- a/stat_test.go +++ b/stat_test.go @@ -1,4 +1,4 @@ -package utilpath +package pathutil import ( "github.com/stretchr/testify/assert" diff --git a/struct.go b/struct.go index df310ee..a88c45b 100644 --- a/struct.go +++ b/struct.go @@ -1,4 +1,4 @@ -package utilpath +package pathutil import ( "os" diff --git a/visit.go b/visit.go index 0ee61b7..0d2a4cd 100644 --- a/visit.go +++ b/visit.go @@ -1,4 +1,4 @@ -package utilpath +package pathutil import ( "os" diff --git a/visit_test.go b/visit_test.go index 2dc4f43..9598782 100644 --- a/visit_test.go +++ b/visit_test.go @@ -1,4 +1,4 @@ -package utilpath +package pathutil import ( "github.com/stretchr/testify/assert" From 82623caa2f3c60e2d2113b253cb932a3ef17c0ea Mon Sep 17 00:00:00 2001 From: Jan Seidl Date: Sun, 30 Apr 2017 00:34:06 +0200 Subject: [PATCH 21/54] add List methods --- open_test.go | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 open_test.go diff --git a/open_test.go b/open_test.go new file mode 100644 index 0000000..45c3b4b --- /dev/null +++ b/open_test.go @@ -0,0 +1,55 @@ +package pathutil + +import ( + "bufio" + "github.com/stretchr/testify/assert" + "testing" +) + +func TestOpenReader(t *testing.T) { + path, err := NewPath("open.go") + + assert.Nil(t, err) + + reader, file, err := path.OpenReader() + assert.Nil(t, err) + defer file.Close() + + assert.IsType(t, new(bufio.Reader), reader) +} + +func TestSlurp(t *testing.T) { + path, err := NewPath("./LICENSE") + + assert.Nil(t, err) + + ctx, err := path.Slurp() + + assert.Equal(t, 1066, len(ctx), "read LICENSE file") +} + +func TestLinesFunc(t *testing.T) { + path, err := NewPath("./LICENSE") + + assert.Nil(t, err) + + countOfLines := 0 + linesFuncError := path.LinesFunc(func(line string) { + countOfLines++ + }) + + assert.Nil(t, linesFuncError) + assert.Equal(t, 21, countOfLines) +} + +func TestLines(t *testing.T) { + path, err := NewPath("./LICENSE") + + assert.Nil(t, err) + + lines, linesFuncError := path.Lines() + + assert.Nil(t, linesFuncError) + assert.Equal(t, 21, len(lines)) + assert.Equal(t, "MIT License", lines[0], "string without new line on end") +} From c72efdf77643d92641dbe7068ee2592c2f508a22 Mon Sep 17 00:00:00 2001 From: Jan Seidl Date: Sun, 30 Apr 2017 09:21:59 +0200 Subject: [PATCH 22/54] rename github repository in badges --- README.md | 14 +++++++------- open.go | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 6b74bf0..933812a 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,10 @@ -# path-go +# pathutil-go -[![Build Status](https://travis-ci.org/JaSei/path-go.svg?branch=implementation)](https://travis-ci.org/JaSei/path-go) -[![Build status](https://ci.appveyor.com/api/projects/status/urj0cf370sr5hjw4?svg=true)](https://ci.appveyor.com/project/JaSei/path-go) -[![Go Report Card](https://goreportcard.com/badge/github.com/JaSei/path-go)](https://goreportcard.com/report/github.com/JaSei/path-go) -[![GoDoc](https://godoc.org/github.com/JaSei/path-go?status.svg)](http://godoc.org/github.com/jasei/path-go) -[![Sourcegraph](https://sourcegraph.com/github.com/jasei/path-go/-/badge.svg)](https://sourcegraph.com/github.com/jasei/path-go?badge) -[![codecov.io](https://codecov.io/github/boennemann/badges/coverage.svg?branch=master)](https://codecov.io/github/jasei/path-go?branch=implementation) +[![Build Status](https://travis-ci.org/JaSei/pathutil-go.svg?branch=implementation)](https://travis-ci.org/JaSei/pathutil-go) +[![Build status](https://ci.appveyor.com/api/projects/status/urj0cf370sr5hjw4?svg=true)](https://ci.appveyor.com/project/JaSei/pathutil-go) +[![Go Report Card](https://goreportcard.com/badge/github.com/JaSei/pathutil-go)](https://goreportcard.com/report/github.com/JaSei/pathutil-go) +[![GoDoc](https://godoc.org/github.com/JaSei/pathutil-go?status.svg)](http://godoc.org/github.com/jasei/pathutil-go) +[![Sourcegraph](https://sourcegraph.com/github.com/jasei/pathutil-go/-/badge.svg)](https://sourcegraph.com/github.com/jasei/pathutil-go?badge) +[![codecov.io](https://codecov.io/github/boennemann/badges/coverage.svg?branch=implementation)](https://codecov.io/github/jasei/pathutil-go?branch=implementation) File path utility inspired by David Golden's [Path::Tiny](https://metacpan.org/pod/Path::Tiny) diff --git a/open.go b/open.go index 2679b77..1b8c048 100644 --- a/open.go +++ b/open.go @@ -35,3 +35,38 @@ func (path *Path) OpenReader() (io.Reader, *os.File, error) { func (path *Path) Slurp() ([]byte, error) { return ioutil.ReadFile(path.String()) } + +// Read lines in file and call linesFunc with line parameter +// +// for example: +// lines := make([]string, 0) +// +// linesFuncError := path.LinesFunc(func(line string) { +// lines = append(lines, line) +// }) +func (path *Path) LinesFunc(linesFunc func(string)) error { + reader, file, err := path.OpenReader() + if err != nil { + return err + } + defer file.Close() + + scanner := bufio.NewScanner(reader) + + for scanner.Scan() { + linesFunc(scanner.Text()) + } + + return scanner.Err() +} + +// Read all lines and return as array of lines +func (path *Path) Lines() ([]string, error) { + lines := make([]string, 0) + + linesFuncError := path.LinesFunc(func(line string) { + lines = append(lines, line) + }) + + return lines, linesFuncError +} From cfa7325d837614dedd46f2a805bcf11cf71c879a Mon Sep 17 00:00:00 2001 From: Jan Seidl Date: Sun, 30 Apr 2017 09:23:55 +0200 Subject: [PATCH 23/54] remove golang 1.3 because failing on travis - some bad default of `go test` in v1.3? --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 2e51911..79cf2ba 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,7 +2,7 @@ language: go go: - 1.2 - - 1.3 +# - 1.3 - 1.4 - 1.5 - 1.6 From 53b9df791d140ca872e5da8dd8c898bc581777df Mon Sep 17 00:00:00 2001 From: Jan Seidl Date: Wed, 14 Jun 2017 10:22:07 +0200 Subject: [PATCH 24/54] add OpenReader add CopyFrom --- base.go | 2 -- constructor.go | 1 - examples/json_test.go | 2 +- examples/recursive_sha256sum_test.go | 2 +- open.go | 46 ++++++++++++++++++++++++++-- struct.go | 5 --- 6 files changed, 46 insertions(+), 12 deletions(-) diff --git a/base.go b/base.go index d6c3165..5452502 100644 --- a/base.go +++ b/base.go @@ -9,7 +9,6 @@ import ( // err := path.Remove() // like os.Remove func (path *Path) Remove() error { - path.file = nil return os.Remove(path.Path) } @@ -17,7 +16,6 @@ func (path *Path) Remove() error { // err := path.RemoveTree // like os.RemoveAll func (path *Path) RemoveTree() error { - path.file = nil return os.RemoveAll(path.Path) } diff --git a/constructor.go b/constructor.go index fcc90e2..01e513d 100644 --- a/constructor.go +++ b/constructor.go @@ -45,7 +45,6 @@ func NewTempFile(options TempFileOpt) (*Path, error) { } return &Path{ - file: file, Path: file.Name(), }, nil } diff --git a/examples/json_test.go b/examples/json_test.go index 7bae86f..8e827e2 100644 --- a/examples/json_test.go +++ b/examples/json_test.go @@ -2,7 +2,7 @@ package pathutil_test import ( "encoding/json" - "github.com/JaSei/pathutil" + "github.com/JaSei/pathutil-go" "github.com/stretchr/testify/assert" "testing" ) diff --git a/examples/recursive_sha256sum_test.go b/examples/recursive_sha256sum_test.go index ac869fb..c341f9b 100644 --- a/examples/recursive_sha256sum_test.go +++ b/examples/recursive_sha256sum_test.go @@ -3,7 +3,7 @@ package pathutil_test import ( "crypto" "fmt" - "github.com/JaSei/pathutil" + "github.com/JaSei/pathutil-go" "github.com/stretchr/testify/assert" "testing" ) diff --git a/open.go b/open.go index 1b8c048..d90642e 100644 --- a/open.go +++ b/open.go @@ -25,11 +25,35 @@ func (path *Path) OpenReader() (io.Reader, *os.File, error) { return nil, nil, err } - path.file = file - return bufio.NewReader(file), file, nil } +// OpenWriter retun bufio io.Writer +// because bufio io.Writer don't implement Close method, +// OpenWriter returns *os.File too +// +// for example: +// path, _ := NewFilePath(FilePathOpt{}) +// writer, file, err := path.OpenWriter() +// if err != nil { +// panic(err) +// } +// defer func(){ +// file.Close() +// file.Sync() +// }() +// +// writer.Write(some_bytes) +// +func (path *Path) OpenWriter() (io.Writer, *os.File, error) { + file, err := os.Open(path.String()) + if err != nil { + return nil, nil, err + } + + return bufio.NewWriter(file), file, nil +} + // Slurp read all file // like ioutil.ReadFile func (path *Path) Slurp() ([]byte, error) { @@ -70,3 +94,21 @@ func (path *Path) Lines() ([]string, error) { return lines, linesFuncError } + +// CopyFrom copy stream from reader to path +// (file after copy close and sync) +func (path *Path) CopyFrom(reader io.Reader) (int64, error) { + writer, file, err := path.OpenWriter() + if err != nil { + return 0, err + } + + defer func() { + file.Close() + file.Sync() + }() + + copyied, err := io.Copy(writer, reader) + + return copyied, err +} diff --git a/struct.go b/struct.go index a88c45b..576d0ca 100644 --- a/struct.go +++ b/struct.go @@ -1,12 +1,7 @@ package pathutil -import ( - "os" -) - type Path struct { Path string - file *os.File } type TempFileOpt struct { From 21978d3fbc8c5103d3ba7b443207bc123fc271f2 Mon Sep 17 00:00:00 2001 From: Jan Seidl Date: Wed, 14 Jun 2017 11:00:31 +0200 Subject: [PATCH 25/54] fix OpenWriter --- open.go | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/open.go b/open.go index d90642e..c50ed97 100644 --- a/open.go +++ b/open.go @@ -28,13 +28,11 @@ func (path *Path) OpenReader() (io.Reader, *os.File, error) { return bufio.NewReader(file), file, nil } -// OpenWriter retun bufio io.Writer -// because bufio io.Writer don't implement Close method, -// OpenWriter returns *os.File too +// OpenWriter retun *os.File // // for example: // path, _ := NewFilePath(FilePathOpt{}) -// writer, file, err := path.OpenWriter() +// file, err := path.OpenWriter() // if err != nil { // panic(err) // } @@ -45,13 +43,13 @@ func (path *Path) OpenReader() (io.Reader, *os.File, error) { // // writer.Write(some_bytes) // -func (path *Path) OpenWriter() (io.Writer, *os.File, error) { - file, err := os.Open(path.String()) +func (path *Path) OpenWriter() (*os.File, error) { + file, err := os.OpenFile(path.String(), os.O_RDWR|os.O_CREATE, 0775) if err != nil { - return nil, nil, err + return nil, err } - return bufio.NewWriter(file), file, nil + return file, err } // Slurp read all file @@ -98,7 +96,7 @@ func (path *Path) Lines() ([]string, error) { // CopyFrom copy stream from reader to path // (file after copy close and sync) func (path *Path) CopyFrom(reader io.Reader) (int64, error) { - writer, file, err := path.OpenWriter() + file, err := path.OpenWriter() if err != nil { return 0, err } @@ -108,7 +106,7 @@ func (path *Path) CopyFrom(reader io.Reader) (int64, error) { file.Sync() }() - copyied, err := io.Copy(writer, reader) + copyied, err := io.Copy(file, reader) return copyied, err } From b51e96ec1f16432ebec2b754258bb2ad75f4c979 Mon Sep 17 00:00:00 2001 From: Jan Seidl Date: Wed, 9 Aug 2017 00:30:07 +0200 Subject: [PATCH 26/54] new download and wc examples --- examples/download_test.go | 35 +++++++++++++++++++++++++++++++++++ examples/wc_test.go | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+) create mode 100644 examples/download_test.go create mode 100644 examples/wc_test.go diff --git a/examples/download_test.go b/examples/download_test.go new file mode 100644 index 0000000..e2af538 --- /dev/null +++ b/examples/download_test.go @@ -0,0 +1,35 @@ +package pathutil_test + +import ( + "github.com/JaSei/pathutil-go" + "github.com/stretchr/testify/assert" + "net/http" + "testing" +) + +func TestDownload(t *testing.T) { + response, err := http.Get("http://example.com") + + assert.Nil(t, err) + defer response.Body.Close() + + temp, err := pathutil.NewTempFile(pathutil.TempFileOpt{}) + + defer temp.Remove() + + assert.Nil(t, err) + + copyied, err := temp.CopyFrom(response.Body) + + if !assert.Nil(t, err) { + t.Log(err) + } + + assert.Equal(t, int64(1270), copyied, "Copy 1270 bytes") + + ctx, err := temp.Slurp() + + assert.Nil(t, err) + + assert.Equal(t, 1270, len(ctx), "Size of http://example.com are 1270") +} diff --git a/examples/wc_test.go b/examples/wc_test.go new file mode 100644 index 0000000..bbf6f43 --- /dev/null +++ b/examples/wc_test.go @@ -0,0 +1,39 @@ +package pathutil_test + +import ( + "github.com/JaSei/pathutil-go" + "github.com/stretchr/testify/assert" + "strings" + "testing" +) + +func wc(path *pathutil.Path) (lines, words, chars int) { + path.LinesFunc(func(line string) { + lines++ + + w := strings.Split(line, " ") + for _, i := range w { + if len(i) > 0 { + words++ + } + } + + chars = len(line) + chars + len("\n") //+newline + }) + + return +} + +func Test(t *testing.T) { + path, err := pathutil.NewPath("../LICENSE") + + assert.Nil(t, err) + + lines, words, chars := wc(path) + + //wc LICENSE + //21 169 1066 LICENSE + assert.Equal(t, 21, lines, "count of lines") + assert.Equal(t, 169, words, "count of words") + assert.Equal(t, 1066, chars, "count of chars") +} From d5eb699c40dc34c708db3036403c86b45e4f694c Mon Sep 17 00:00:00 2001 From: Jan Seidl Date: Wed, 9 Aug 2017 15:21:39 +0200 Subject: [PATCH 27/54] windows slash fix in String method --- base.go | 2 +- constructor.go | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/base.go b/base.go index 5452502..10ccc2c 100644 --- a/base.go +++ b/base.go @@ -23,7 +23,7 @@ func (path *Path) RemoveTree() error { // this representation is linux like (slash as separator) // for os specific string use Canonpath method func (path *Path) String() string { - return filepath.Clean(path.Path) + return path.Path } // Canonpath retrun path with right os separator diff --git a/constructor.go b/constructor.go index 01e513d..5794294 100644 --- a/constructor.go +++ b/constructor.go @@ -15,7 +15,8 @@ import ( // func NewPath(path ...string) (*Path, error) { newPath := new(Path) - newPath.Path = strings.Replace(filepath.Join(path...), "\\", "/", -1) + + newPath.Path = strings.Replace(filepath.Clean(filepath.Join(path...)), "\\", "/", -1) if len(newPath.Path) == 0 { return nil, errors.New("Paths requires defined, positive-lengths parts") From 5f5ff2d2b71e27ec82b43b65d4f1c4b28230b55c Mon Sep 17 00:00:00 2001 From: Jan Seidl Date: Wed, 9 Aug 2017 15:33:49 +0200 Subject: [PATCH 28/54] fix bad path in appveyor config --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 6ca1199..5a2903a 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,6 +1,6 @@ version: "{build}" -clone_folder: c:\go\src\github.com\jasei\path-go +clone_folder: c:\go\src\github.com\JaSei\path-go #os: Windows Server 2012 R2 platform: x64 From 0d0f3358b1585a3a80dc98205dd6abdc7b835d6c Mon Sep 17 00:00:00 2001 From: Jan Seidl Date: Wed, 9 Aug 2017 15:37:42 +0200 Subject: [PATCH 29/54] constructor fix --- constructor.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/constructor.go b/constructor.go index 5794294..da2348c 100644 --- a/constructor.go +++ b/constructor.go @@ -16,12 +16,13 @@ import ( func NewPath(path ...string) (*Path, error) { newPath := new(Path) - newPath.Path = strings.Replace(filepath.Clean(filepath.Join(path...)), "\\", "/", -1) - - if len(newPath.Path) == 0 { + joinPath := filepath.Join(path...) + if len(joinPath) == 0 { return nil, errors.New("Paths requires defined, positive-lengths parts") } + newPath.Path = strings.Replace(filepath.Clean(joinPath), "\\", "/", -1) + return newPath, nil } From e534568c4afafd96aef0000a6f868c685c540441 Mon Sep 17 00:00:00 2001 From: Jan Seidl Date: Wed, 9 Aug 2017 15:43:46 +0200 Subject: [PATCH 30/54] fix appveoyr (win) test --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 5a2903a..ff554df 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,6 +1,6 @@ version: "{build}" -clone_folder: c:\go\src\github.com\JaSei\path-go +clone_folder: c:\go\src\github.com\JaSei\pathutil-go #os: Windows Server 2012 R2 platform: x64 From eeaffc776cbd6e164c75b0d776d949f26dbee0ac Mon Sep 17 00:00:00 2001 From: Jan Seidl Date: Wed, 9 Aug 2017 16:03:56 +0200 Subject: [PATCH 31/54] fix windows tests --- constructor.go | 4 +--- stat_test.go | 7 +++++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/constructor.go b/constructor.go index da2348c..b59523b 100644 --- a/constructor.go +++ b/constructor.go @@ -46,7 +46,5 @@ func NewTempFile(options TempFileOpt) (*Path, error) { return nil, err } - return &Path{ - Path: file.Name(), - }, nil + return NewPath(file.Name()) } diff --git a/stat_test.go b/stat_test.go index 95b3cc1..cd8d859 100644 --- a/stat_test.go +++ b/stat_test.go @@ -3,6 +3,7 @@ package pathutil import ( "github.com/stretchr/testify/assert" "os" + "runtime" "testing" ) @@ -36,8 +37,10 @@ func TestIsFile(t *testing.T) { path, _ = NewPath("/safjasfjalfja") assert.Exactly(t, false, path.IsFile(), "unexists something isn't file") - path, _ = NewPath("/dev/zero") - assert.Exactly(t, true, path.IsFile(), "/dev/zero is file") + if runtime.GOOS != "windows" { + path, _ = NewPath("/dev/zero") + assert.Exactly(t, true, path.IsFile(), "/dev/zero is file") + } //symlink test } From 36746bef9099ccf14be16f178302fc8e99a4b30a Mon Sep 17 00:00:00 2001 From: Jan Seidl Date: Fri, 20 Oct 2017 00:03:11 +0200 Subject: [PATCH 32/54] implement Spew --- examples/recursive_sha256sum_test.go | 2 +- open.go | 51 +++++++++++++++++++++++++++- open_test.go | 14 +++++++- 3 files changed, 64 insertions(+), 3 deletions(-) diff --git a/examples/recursive_sha256sum_test.go b/examples/recursive_sha256sum_test.go index c341f9b..19fda2f 100644 --- a/examples/recursive_sha256sum_test.go +++ b/examples/recursive_sha256sum_test.go @@ -9,7 +9,7 @@ import ( ) func TestVisitRecursiveAndHashAllFiles(t *testing.T) { - path, err := pathutil.NewPath("/tmp") + path, err := pathutil.NewPath("tree") assert.Nil(t, err) path.Visit( diff --git a/open.go b/open.go index c50ed97..decae9c 100644 --- a/open.go +++ b/open.go @@ -54,10 +54,59 @@ func (path *Path) OpenWriter() (*os.File, error) { // Slurp read all file // like ioutil.ReadFile -func (path *Path) Slurp() ([]byte, error) { +func (path *Path) Slurp() (string, error) { + bytes, err := path.SlurpBytes() + if err != nil { + return "", err + } + + return string(bytes[:]), nil +} + +func (path *Path) SlurpBytes() ([]byte, error) { return ioutil.ReadFile(path.String()) } +// Spew write string to file +func (path *Path) Spew(content string) error { + file, err := path.OpenWriter() + if err != nil { + return err + } + + defer func() { + if err := file.Close(); err != nil { + panic(err) + } + }() + + if _, err := file.WriteString(content); err != nil { + return err + } + + return nil +} + +// SpewBytes write bytes to file +func (path *Path) SpewBytes(bytes []byte) error { + file, err := path.OpenWriter() + if err != nil { + return err + } + + defer func() { + if err := file.Close(); err != nil { + panic(err) + } + }() + + if _, err := file.Write(bytes); err != nil { + return err + } + + return nil +} + // Read lines in file and call linesFunc with line parameter // // for example: diff --git a/open_test.go b/open_test.go index 45c3b4b..a146ee8 100644 --- a/open_test.go +++ b/open_test.go @@ -23,7 +23,7 @@ func TestSlurp(t *testing.T) { assert.Nil(t, err) - ctx, err := path.Slurp() + ctx, err := path.SlurpBytes() assert.Equal(t, 1066, len(ctx), "read LICENSE file") } @@ -53,3 +53,15 @@ func TestLines(t *testing.T) { assert.Equal(t, 21, len(lines)) assert.Equal(t, "MIT License", lines[0], "string without new line on end") } + +func TestSpew(t *testing.T) { + temp, err := NewTempFile(TempFileOpt{}) + assert.NoError(t, err) + + err = temp.Spew("kukuc") + assert.NoError(t, err) + + ctx, err := temp.Slurp() + assert.NoError(t, err) + assert.Equal(t, "kukuc", ctx) +} From 64c27b032b369c60f3758bff93addb05afc5f6d7 Mon Sep 17 00:00:00 2001 From: Jan Seidl Date: Fri, 20 Oct 2017 09:36:57 +0200 Subject: [PATCH 33/54] fix test --- examples/json_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/json_test.go b/examples/json_test.go index 8e827e2..237cac2 100644 --- a/examples/json_test.go +++ b/examples/json_test.go @@ -50,7 +50,7 @@ func TestLoadJsonViaSlurp(t *testing.T) { path, err := pathutil.NewPath("example.json") assert.Nil(t, err) - jsonBytes, err := path.Slurp() + jsonBytes, err := path.SlurpBytes() assert.Nil(t, err) decodedJson := new(FileInfo) From f48cf8da27f47b06e71b3237925021308d8bd946 Mon Sep 17 00:00:00 2001 From: Jan Seidl Date: Mon, 23 Oct 2017 13:38:07 +0200 Subject: [PATCH 34/54] add rename method --- constructor.go | 5 +++++ rename.go | 17 +++++++++++++++++ rename_test.go | 27 +++++++++++++++++++++++++++ 3 files changed, 49 insertions(+) create mode 100644 rename.go create mode 100644 rename_test.go diff --git a/constructor.go b/constructor.go index b59523b..56821ef 100644 --- a/constructor.go +++ b/constructor.go @@ -31,6 +31,11 @@ func NewPath(path ...string) (*Path, error) { // for cleanup use defer // temp, err := NewTempFile(TempFileOpt{}) // defer temp.Remove() +// +// if you need only temp file name, you must delete file +// temp, err := NewTempFile(TempFileOpt{}) +// temp.Remove() +// func NewTempFile(options TempFileOpt) (*Path, error) { dir := options.Dir diff --git a/rename.go b/rename.go new file mode 100644 index 0000000..9f888f8 --- /dev/null +++ b/rename.go @@ -0,0 +1,17 @@ +package pathutil + +import ( + "os" +) + +// Rename path to new path +func (old *Path) Rename(new string) (*Path, error) { + newPath, err := NewPath(new) + if err != nil { + return nil, err + } + + err = os.Rename(old.Canonpath(), newPath.Canonpath()) + + return newPath, err +} diff --git a/rename_test.go b/rename_test.go new file mode 100644 index 0000000..1b9b84c --- /dev/null +++ b/rename_test.go @@ -0,0 +1,27 @@ +package pathutil + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestRename(t *testing.T) { + a, err := NewTempFile(TempFileOpt{}) + assert.NoError(t, err) + + b, err := NewTempFile(TempFileOpt{}) + assert.NoError(t, err) + assert.NoError(t, b.Remove()) + + assert.True(t, a.Exists(), "path a exists") + assert.False(t, b.Exists(), "path b don't") + + c, err := a.Rename(b.Canonpath()) + assert.NoError(t, err) + + assert.False(t, a.Exists(), "After raname path a not exists") + assert.True(t, b.Exists(), "After raname path b exists") + + assert.Equal(t, b, c, "Path b and c is same") +} From 7e0249ea5386213d92bb3c2a65adbd52487a0f98 Mon Sep 17 00:00:00 2001 From: Jan Seidl Date: Thu, 26 Oct 2017 17:34:01 +0200 Subject: [PATCH 35/54] * add NewTempDir function * breaking change TempFileOpt renamed to TempDirOpt --- Gopkg.toml | 7 +++++++ base.go | 15 --------------- copy_test.go | 2 +- crypto_test.go | 2 +- makepath.go | 16 ++++++++++++++++ makepath_test.go | 25 +++++++++++++++++++++++++ constructor.go => new.go | 30 +++++++++++++++++++----------- constructor_test.go => new_test.go | 6 +++--- open_test.go | 2 +- remove.go | 19 +++++++++++++++++++ remove_test.go | 15 +++++++++++++++ struct.go | 6 ++++-- 12 files changed, 111 insertions(+), 34 deletions(-) create mode 100644 Gopkg.toml create mode 100644 makepath.go create mode 100644 makepath_test.go rename constructor.go => new.go (55%) rename constructor_test.go => new_test.go (80%) create mode 100644 remove.go create mode 100644 remove_test.go diff --git a/Gopkg.toml b/Gopkg.toml new file mode 100644 index 0000000..d9fbc12 --- /dev/null +++ b/Gopkg.toml @@ -0,0 +1,7 @@ +[[constraint]] + name = "github.com/pkg/errors" + version = "0.8.0" + +[[constraint]] + name = "github.com/stretchr/testify" + version = "1.1.4" diff --git a/base.go b/base.go index 10ccc2c..844fdbd 100644 --- a/base.go +++ b/base.go @@ -1,24 +1,9 @@ package pathutil import ( - "os" "path/filepath" ) -// Remove file -// err := path.Remove() -// like os.Remove -func (path *Path) Remove() error { - return os.Remove(path.Path) -} - -// Remove tree of files -// err := path.RemoveTree -// like os.RemoveAll -func (path *Path) RemoveTree() error { - return os.RemoveAll(path.Path) -} - // String return stable string representation of path // this representation is linux like (slash as separator) // for os specific string use Canonpath method diff --git a/copy_test.go b/copy_test.go index 0a655ad..4ea6ef1 100644 --- a/copy_test.go +++ b/copy_test.go @@ -8,7 +8,7 @@ import ( func TestCopyFileDstFileExists(t *testing.T) { src, _ := NewPath("copy_test.go") - dst, err := NewTempFile(TempFileOpt{}) + dst, err := NewTempFile(TempOpt{}) assert.Nil(t, err) defer dst.Remove() diff --git a/crypto_test.go b/crypto_test.go index 8aff056..d439d1c 100644 --- a/crypto_test.go +++ b/crypto_test.go @@ -11,7 +11,7 @@ const emptyFileSha256Hex = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495 var emptyFileSha256Bin = []uint8{0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c, 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55} func TestPathCrypto(t *testing.T) { - path, err := NewTempFile(TempFileOpt{}) + path, err := NewTempFile(TempOpt{}) assert.Nil(t, err) defer path.Remove() diff --git a/makepath.go b/makepath.go new file mode 100644 index 0000000..670eeeb --- /dev/null +++ b/makepath.go @@ -0,0 +1,16 @@ +package pathutil + +import ( + "os" +) + +// Make path create directory(ies) in path if not exists (like `mkdir -p`) with default 0777 mode +// if you need set mode, use `MakePathMode` +func (path *Path) MakePath() error { + return path.MakePathMode(0777) +} + +// Make path create directory(ies) in path if not exists (like `mkdir -p`) with default given mode +func (path *Path) MakePathMode(mode os.FileMode) error { + return os.MkdirAll(path.Canonpath(), mode) +} diff --git a/makepath_test.go b/makepath_test.go new file mode 100644 index 0000000..38d3a79 --- /dev/null +++ b/makepath_test.go @@ -0,0 +1,25 @@ +package pathutil + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestMakePath(t *testing.T) { + tempdir, err := NewTempDir(TempOpt{}) + assert.NoError(t, err) + + defer func() { + assert.NoError(t, tempdir.RemoveTree()) + }() + + newPath, err := NewPath(tempdir.String(), "a/b/c") + assert.NoError(t, err) + + assert.False(t, newPath.Exists()) + + assert.NoError(t, newPath.MakePath()) + + assert.True(t, newPath.IsDir()) +} diff --git a/constructor.go b/new.go similarity index 55% rename from constructor.go rename to new.go index 56821ef..1dda9af 100644 --- a/constructor.go +++ b/new.go @@ -1,11 +1,11 @@ package pathutil import ( - "errors" "io/ioutil" - "os" "path/filepath" "strings" + + "github.com/pkg/errors" ) // NewPath construct *Path @@ -29,7 +29,7 @@ func NewPath(path ...string) (*Path, error) { // NewTempFile create temp file // // for cleanup use defer -// temp, err := NewTempFile(TempFileOpt{}) +// temp, err := NewTempFile(TempOpt{}) // defer temp.Remove() // // if you need only temp file name, you must delete file @@ -37,19 +37,27 @@ func NewPath(path ...string) (*Path, error) { // temp.Remove() // -func NewTempFile(options TempFileOpt) (*Path, error) { - dir := options.Dir - - if dir == "" { - dir = os.TempDir() +func NewTempFile(options TempOpt) (*Path, error) { + file, err := ioutil.TempFile(options.Dir, options.Prefix) + if err != nil { + return nil, errors.Wrapf(err, "NewTempFile(%+v) fail", options) } - file, err := ioutil.TempFile(dir, options.Prefix) defer file.Close() + return NewPath(file.Name()) +} + +// NewTempDir create temp directory +// +// for cleanup use `defer` +// tempdir, err := pathutil.NewTempDir(TempOpt{}) +// defer tempdir.RemoveTree() +func NewTempDir(options TempOpt) (*Path, error) { + dir, err := ioutil.TempDir(options.Dir, options.Prefix) if err != nil { - return nil, err + return nil, errors.Wrapf(err, "NewTempDir(%+v) fail", options) } - return NewPath(file.Name()) + return NewPath(dir) } diff --git a/constructor_test.go b/new_test.go similarity index 80% rename from constructor_test.go rename to new_test.go index 134f568..eb798ea 100644 --- a/constructor_test.go +++ b/new_test.go @@ -16,19 +16,19 @@ func TestNewPath(t *testing.T) { } func TestNewTempFile(t *testing.T) { - temp, err := NewTempFile(TempFileOpt{}) + temp, err := NewTempFile(TempOpt{}) defer temp.Remove() assert.NotNil(t, temp) assert.Nil(t, err) - temp, err = NewTempFile(TempFileOpt{Dir: "."}) + temp, err = NewTempFile(TempOpt{Dir: "."}) defer temp.Remove() assert.NotNil(t, temp) assert.Nil(t, err) } func TestTempFile(t *testing.T) { - temp, err := NewTempFile(TempFileOpt{Prefix: "bla"}) + temp, err := NewTempFile(TempOpt{Prefix: "bla"}) defer temp.Remove() assert.NotNil(t, temp) diff --git a/open_test.go b/open_test.go index a146ee8..5ad2f4c 100644 --- a/open_test.go +++ b/open_test.go @@ -55,7 +55,7 @@ func TestLines(t *testing.T) { } func TestSpew(t *testing.T) { - temp, err := NewTempFile(TempFileOpt{}) + temp, err := NewTempFile(TempOpt{}) assert.NoError(t, err) err = temp.Spew("kukuc") diff --git a/remove.go b/remove.go new file mode 100644 index 0000000..ab2fe2f --- /dev/null +++ b/remove.go @@ -0,0 +1,19 @@ +package pathutil + +import ( + "os" +) + +// Remove file +// err := path.Remove() +// like os.Remove +func (path *Path) Remove() error { + return os.Remove(path.Path) +} + +// Remove tree of directory(ies) include files +// err := path.RemoveTree +// like os.RemoveAll +func (path *Path) RemoveTree() error { + return os.RemoveAll(path.Canonpath()) +} diff --git a/remove_test.go b/remove_test.go new file mode 100644 index 0000000..53e55dc --- /dev/null +++ b/remove_test.go @@ -0,0 +1,15 @@ +package pathutil + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestRemove(t *testing.T) { + temp, err := NewTempFile(TempOpt{}) + assert.NoError(t, err) + assert.True(t, temp.Exists()) + assert.NoError(t, temp.Remove()) + assert.False(t, temp.Exists()) +} diff --git a/struct.go b/struct.go index 576d0ca..1fa9df5 100644 --- a/struct.go +++ b/struct.go @@ -4,7 +4,9 @@ type Path struct { Path string } -type TempFileOpt struct { - Dir string +type TempOpt struct { + // directory where is temp file/dir create, empty string `""` (default) means TEMPDIR (`os.TempDir`) + Dir string + // name beginning with prefix Prefix string } From 549f0695a453f6d58464415861cfff6820252642 Mon Sep 17 00:00:00 2001 From: Jan Seidl Date: Fri, 27 Oct 2017 09:18:32 +0200 Subject: [PATCH 36/54] * add Chdir function * fix examples --- base_test.go | 3 ++- chdir.go | 21 +++++++++++++++++++++ chdir_test.go | 34 ++++++++++++++++++++++++++++++++++ examples/download_test.go | 7 +++++-- new.go | 19 +++++++++++++++++++ open.go | 6 ++++-- rename_test.go | 4 ++-- struct.go | 7 ------- 8 files changed, 87 insertions(+), 14 deletions(-) create mode 100644 chdir.go create mode 100644 chdir_test.go diff --git a/base_test.go b/base_test.go index 8f62c57..2eab929 100644 --- a/base_test.go +++ b/base_test.go @@ -2,9 +2,10 @@ package pathutil import ( "fmt" - "github.com/stretchr/testify/assert" "path/filepath" "testing" + + "github.com/stretchr/testify/assert" ) func TestString(t *testing.T) { diff --git a/chdir.go b/chdir.go new file mode 100644 index 0000000..3301a81 --- /dev/null +++ b/chdir.go @@ -0,0 +1,21 @@ +package pathutil + +import ( + "os" + + "github.com/pkg/errors" +) + +// Chdir change current working directory do the path and return old current working directory +func (path *Path) Chdir() (*Path, error) { + oldPath, err := Cwd() + if err != nil { + return nil, errors.Wrap(err, "Cwd fail") + } + + if err := os.Chdir(path.Canonpath()); err != nil { + return nil, errors.Wrapf(err, "Chdir(%s) fail", path) + } + + return oldPath, nil +} diff --git a/chdir_test.go b/chdir_test.go new file mode 100644 index 0000000..b705632 --- /dev/null +++ b/chdir_test.go @@ -0,0 +1,34 @@ +package pathutil + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestChdir(t *testing.T) { + tempdir, err := NewTempDir(TempOpt{}) + assert.NoError(t, err) + + cwd, err := Cwd() + assert.NoError(t, err) + + assert.NotEqual(t, tempdir, cwd, "Current working directory isn't same as tempdir") + + oldCwd, err := tempdir.Chdir() + assert.NoError(t, err) + + // return cwd back + defer func() { + _, err = oldCwd.Chdir() + assert.NoError(t, err) + }() + + assert.NotEqual(t, tempdir, cwd, "Old current working directory isn't same as tempdir") + assert.Equal(t, oldCwd, cwd, "Old current working directory is same as returned oldCwd after Chdir") + + actualCwd, err := Cwd() + assert.NoError(t, err) + + assert.Equal(t, tempdir, actualCwd, "Actual current working directory is tempdir") +} diff --git a/examples/download_test.go b/examples/download_test.go index e2af538..03db52a 100644 --- a/examples/download_test.go +++ b/examples/download_test.go @@ -10,10 +10,13 @@ import ( func TestDownload(t *testing.T) { response, err := http.Get("http://example.com") - assert.Nil(t, err) + if !assert.NoError(t, err) { + t.Fatal("Connectivity problem") + } + defer response.Body.Close() - temp, err := pathutil.NewTempFile(pathutil.TempFileOpt{}) + temp, err := pathutil.NewTempFile(pathutil.TempOpt{}) defer temp.Remove() diff --git a/new.go b/new.go index 1dda9af..b8a97bd 100644 --- a/new.go +++ b/new.go @@ -2,6 +2,7 @@ package pathutil import ( "io/ioutil" + "os" "path/filepath" "strings" @@ -26,6 +27,14 @@ func NewPath(path ...string) (*Path, error) { return newPath, nil } +//TempOpt is struct for configure new tempdir or tempfile +type TempOpt struct { + // directory where is temp file/dir create, empty string `""` (default) means TEMPDIR (`os.TempDir`) + Dir string + // name beginning with prefix + Prefix string +} + // NewTempFile create temp file // // for cleanup use defer @@ -61,3 +70,13 @@ func NewTempDir(options TempOpt) (*Path, error) { return NewPath(dir) } + +// Cwd create new path from current working directory +func Cwd() (*Path, error) { + cwd, err := os.Getwd() + if err != nil { + return nil, errors.Wrap(err, "Getwd fail") + } + + return NewPath(cwd) +} diff --git a/open.go b/open.go index decae9c..8ab4e4d 100644 --- a/open.go +++ b/open.go @@ -5,6 +5,8 @@ import ( "io" "io/ioutil" "os" + + "github.com/pkg/errors" ) // OpenReader retun bufio io.Reader @@ -20,9 +22,9 @@ import ( // defer file.Close() // func (path *Path) OpenReader() (io.Reader, *os.File, error) { - file, err := os.Open(path.String()) + file, err := os.Open(path.Canonpath()) if err != nil { - return nil, nil, err + return nil, nil, errors.Wrapf(err, "OpenReader on path %s fail (%+v)", path, path) } return bufio.NewReader(file), file, nil diff --git a/rename_test.go b/rename_test.go index 1b9b84c..09619d6 100644 --- a/rename_test.go +++ b/rename_test.go @@ -7,10 +7,10 @@ import ( ) func TestRename(t *testing.T) { - a, err := NewTempFile(TempFileOpt{}) + a, err := NewTempFile(TempOpt{}) assert.NoError(t, err) - b, err := NewTempFile(TempFileOpt{}) + b, err := NewTempFile(TempOpt{}) assert.NoError(t, err) assert.NoError(t, b.Remove()) diff --git a/struct.go b/struct.go index 1fa9df5..824e057 100644 --- a/struct.go +++ b/struct.go @@ -3,10 +3,3 @@ package pathutil type Path struct { Path string } - -type TempOpt struct { - // directory where is temp file/dir create, empty string `""` (default) means TEMPDIR (`os.TempDir`) - Dir string - // name beginning with prefix - Prefix string -} From 70967fc582651fbc022e3c7ece2e8ea2478af2ed Mon Sep 17 00:00:00 2001 From: Jan Seidl Date: Fri, 27 Oct 2017 12:55:33 +0200 Subject: [PATCH 37/54] refactoring - Path is interface --- base.go | 6 +-- chdir.go | 2 +- copy.go | 2 +- crypto.go | 2 +- examples/recursive_sha256sum_test.go | 2 +- examples/wc_test.go | 4 +- interface.go | 56 ++++++++++++++++++++++++++++ makepath.go | 4 +- new.go | 10 ++--- open.go | 24 ++++++------ open_test.go | 4 +- remove.go | 4 +- rename.go | 2 +- stat.go | 10 ++--- struct.go | 2 +- visit.go | 8 +--- visit_test.go | 4 +- 17 files changed, 98 insertions(+), 48 deletions(-) create mode 100644 interface.go diff --git a/base.go b/base.go index 844fdbd..db498f8 100644 --- a/base.go +++ b/base.go @@ -7,18 +7,18 @@ import ( // String return stable string representation of path // this representation is linux like (slash as separator) // for os specific string use Canonpath method -func (path *Path) String() string { +func (path pathImpl) String() string { return path.Path } // Canonpath retrun path with right os separator -func (path *Path) Canonpath() string { +func (path pathImpl) Canonpath() string { return filepath.FromSlash(filepath.Clean(path.Path)) } // Basename // like path/filepath.Base -func (path *Path) Basename() string { +func (path pathImpl) Basename() string { if path.Path == "/" { return "" } diff --git a/chdir.go b/chdir.go index 3301a81..5f9a2d6 100644 --- a/chdir.go +++ b/chdir.go @@ -7,7 +7,7 @@ import ( ) // Chdir change current working directory do the path and return old current working directory -func (path *Path) Chdir() (*Path, error) { +func (path pathImpl) Chdir() (Path, error) { oldPath, err := Cwd() if err != nil { return nil, errors.Wrap(err, "Cwd fail") diff --git a/copy.go b/copy.go index 2f746f6..3aa6212 100644 --- a/copy.go +++ b/copy.go @@ -5,7 +5,7 @@ import ( "os" ) -func (srcPath *Path) CopyFile(dst string) (*Path, error) { +func (srcPath pathImpl) CopyFile(dst string) (Path, error) { dstPath, err := NewPath(dst) if err != nil { return nil, err diff --git a/crypto.go b/crypto.go index c6ccdec..a1069c4 100644 --- a/crypto.go +++ b/crypto.go @@ -14,7 +14,7 @@ import ( // hash, err := path.Crypto(crypto.SHA256) // fmt.Println(hash.HexSum()) -func (path *Path) Crypto(hash crypto.Hash) (*CryptoHash, error) { +func (path pathImpl) Crypto(hash crypto.Hash) (*CryptoHash, error) { reader, file, err := path.OpenReader() if err != nil { return nil, err diff --git a/examples/recursive_sha256sum_test.go b/examples/recursive_sha256sum_test.go index 19fda2f..1cb8dde 100644 --- a/examples/recursive_sha256sum_test.go +++ b/examples/recursive_sha256sum_test.go @@ -13,7 +13,7 @@ func TestVisitRecursiveAndHashAllFiles(t *testing.T) { assert.Nil(t, err) path.Visit( - func(path *pathutil.Path) { + func(path pathutil.Path) { if path.IsDir() { return } diff --git a/examples/wc_test.go b/examples/wc_test.go index bbf6f43..99ba657 100644 --- a/examples/wc_test.go +++ b/examples/wc_test.go @@ -7,8 +7,8 @@ import ( "testing" ) -func wc(path *pathutil.Path) (lines, words, chars int) { - path.LinesFunc(func(line string) { +func wc(path pathutil.Path) (lines, words, chars int) { + path.LinesWalker(func(line string) { lines++ w := strings.Split(line, " ") diff --git a/interface.go b/interface.go new file mode 100644 index 0000000..0f287a4 --- /dev/null +++ b/interface.go @@ -0,0 +1,56 @@ +package pathutil + +import ( + "crypto" + "io" + "os" +) + +type VisitFunc func(path Path) + +type VisitOpt struct { + Recurse bool +} + +type LinesFunc func(string) + +type Path interface { + String() string + Canonpath() string + Basename() string + + Chdir() (Path, error) + Rename(string) (Path, error) + + Stat() (os.FileInfo, error) + + IsDir() bool + Exists() bool + IsFile() bool + IsRegularFile() bool + + Remove() error + RemoveTree() error + + Visit(VisitFunc, VisitOpt) + CopyFile(string) (Path, error) + + CopyFrom(io.Reader) (int64, error) + + Crypto(crypto.Hash) (*CryptoHash, error) + + MakePath() error + MakePathMode(os.FileMode) error + + OpenReader() (io.Reader, *os.File, error) + OpenWriter() (*os.File, error) + + Slurp() (string, error) + SlurpBytes() ([]byte, error) + + Spew(string) error + SpewBytes([]byte) error + + Lines() ([]string, error) + LinesWalker(LinesFunc) error +} diff --git a/makepath.go b/makepath.go index 670eeeb..c20ddbd 100644 --- a/makepath.go +++ b/makepath.go @@ -6,11 +6,11 @@ import ( // Make path create directory(ies) in path if not exists (like `mkdir -p`) with default 0777 mode // if you need set mode, use `MakePathMode` -func (path *Path) MakePath() error { +func (path pathImpl) MakePath() error { return path.MakePathMode(0777) } // Make path create directory(ies) in path if not exists (like `mkdir -p`) with default given mode -func (path *Path) MakePathMode(mode os.FileMode) error { +func (path pathImpl) MakePathMode(mode os.FileMode) error { return os.MkdirAll(path.Canonpath(), mode) } diff --git a/new.go b/new.go index b8a97bd..3ca2b86 100644 --- a/new.go +++ b/new.go @@ -14,8 +14,8 @@ import ( // for example // path := NewPath("/home/test", ".vimrc") // -func NewPath(path ...string) (*Path, error) { - newPath := new(Path) +func NewPath(path ...string) (Path, error) { + newPath := pathImpl{} joinPath := filepath.Join(path...) if len(joinPath) == 0 { @@ -46,7 +46,7 @@ type TempOpt struct { // temp.Remove() // -func NewTempFile(options TempOpt) (*Path, error) { +func NewTempFile(options TempOpt) (Path, error) { file, err := ioutil.TempFile(options.Dir, options.Prefix) if err != nil { return nil, errors.Wrapf(err, "NewTempFile(%+v) fail", options) @@ -62,7 +62,7 @@ func NewTempFile(options TempOpt) (*Path, error) { // for cleanup use `defer` // tempdir, err := pathutil.NewTempDir(TempOpt{}) // defer tempdir.RemoveTree() -func NewTempDir(options TempOpt) (*Path, error) { +func NewTempDir(options TempOpt) (Path, error) { dir, err := ioutil.TempDir(options.Dir, options.Prefix) if err != nil { return nil, errors.Wrapf(err, "NewTempDir(%+v) fail", options) @@ -72,7 +72,7 @@ func NewTempDir(options TempOpt) (*Path, error) { } // Cwd create new path from current working directory -func Cwd() (*Path, error) { +func Cwd() (Path, error) { cwd, err := os.Getwd() if err != nil { return nil, errors.Wrap(err, "Getwd fail") diff --git a/open.go b/open.go index 8ab4e4d..8802122 100644 --- a/open.go +++ b/open.go @@ -21,7 +21,7 @@ import ( // } // defer file.Close() // -func (path *Path) OpenReader() (io.Reader, *os.File, error) { +func (path pathImpl) OpenReader() (io.Reader, *os.File, error) { file, err := os.Open(path.Canonpath()) if err != nil { return nil, nil, errors.Wrapf(err, "OpenReader on path %s fail (%+v)", path, path) @@ -45,7 +45,7 @@ func (path *Path) OpenReader() (io.Reader, *os.File, error) { // // writer.Write(some_bytes) // -func (path *Path) OpenWriter() (*os.File, error) { +func (path pathImpl) OpenWriter() (*os.File, error) { file, err := os.OpenFile(path.String(), os.O_RDWR|os.O_CREATE, 0775) if err != nil { return nil, err @@ -56,7 +56,7 @@ func (path *Path) OpenWriter() (*os.File, error) { // Slurp read all file // like ioutil.ReadFile -func (path *Path) Slurp() (string, error) { +func (path pathImpl) Slurp() (string, error) { bytes, err := path.SlurpBytes() if err != nil { return "", err @@ -65,12 +65,12 @@ func (path *Path) Slurp() (string, error) { return string(bytes[:]), nil } -func (path *Path) SlurpBytes() ([]byte, error) { +func (path pathImpl) SlurpBytes() ([]byte, error) { return ioutil.ReadFile(path.String()) } // Spew write string to file -func (path *Path) Spew(content string) error { +func (path pathImpl) Spew(content string) error { file, err := path.OpenWriter() if err != nil { return err @@ -90,7 +90,7 @@ func (path *Path) Spew(content string) error { } // SpewBytes write bytes to file -func (path *Path) SpewBytes(bytes []byte) error { +func (path pathImpl) SpewBytes(bytes []byte) error { file, err := path.OpenWriter() if err != nil { return err @@ -109,15 +109,15 @@ func (path *Path) SpewBytes(bytes []byte) error { return nil } -// Read lines in file and call linesFunc with line parameter +// LinesWalker read lines in file and call LinesFunc with line parameter // // for example: // lines := make([]string, 0) // -// linesFuncError := path.LinesFunc(func(line string) { +// linesFuncError := path.LinesWalker(func(line string) { // lines = append(lines, line) // }) -func (path *Path) LinesFunc(linesFunc func(string)) error { +func (path pathImpl) LinesWalker(linesFunc LinesFunc) error { reader, file, err := path.OpenReader() if err != nil { return err @@ -134,10 +134,10 @@ func (path *Path) LinesFunc(linesFunc func(string)) error { } // Read all lines and return as array of lines -func (path *Path) Lines() ([]string, error) { +func (path pathImpl) Lines() ([]string, error) { lines := make([]string, 0) - linesFuncError := path.LinesFunc(func(line string) { + linesFuncError := path.LinesWalker(func(line string) { lines = append(lines, line) }) @@ -146,7 +146,7 @@ func (path *Path) Lines() ([]string, error) { // CopyFrom copy stream from reader to path // (file after copy close and sync) -func (path *Path) CopyFrom(reader io.Reader) (int64, error) { +func (path pathImpl) CopyFrom(reader io.Reader) (int64, error) { file, err := path.OpenWriter() if err != nil { return 0, err diff --git a/open_test.go b/open_test.go index 5ad2f4c..bdfc6df 100644 --- a/open_test.go +++ b/open_test.go @@ -28,13 +28,13 @@ func TestSlurp(t *testing.T) { assert.Equal(t, 1066, len(ctx), "read LICENSE file") } -func TestLinesFunc(t *testing.T) { +func TestLinesWalker(t *testing.T) { path, err := NewPath("./LICENSE") assert.Nil(t, err) countOfLines := 0 - linesFuncError := path.LinesFunc(func(line string) { + linesFuncError := path.LinesWalker(func(line string) { countOfLines++ }) diff --git a/remove.go b/remove.go index ab2fe2f..3013385 100644 --- a/remove.go +++ b/remove.go @@ -7,13 +7,13 @@ import ( // Remove file // err := path.Remove() // like os.Remove -func (path *Path) Remove() error { +func (path pathImpl) Remove() error { return os.Remove(path.Path) } // Remove tree of directory(ies) include files // err := path.RemoveTree // like os.RemoveAll -func (path *Path) RemoveTree() error { +func (path pathImpl) RemoveTree() error { return os.RemoveAll(path.Canonpath()) } diff --git a/rename.go b/rename.go index 9f888f8..1aaeaa8 100644 --- a/rename.go +++ b/rename.go @@ -5,7 +5,7 @@ import ( ) // Rename path to new path -func (old *Path) Rename(new string) (*Path, error) { +func (old pathImpl) Rename(new string) (Path, error) { newPath, err := NewPath(new) if err != nil { return nil, err diff --git a/stat.go b/stat.go index e1d0b1e..3998a97 100644 --- a/stat.go +++ b/stat.go @@ -6,7 +6,7 @@ import ( ) // Stat return os.FileInfo -func (path *Path) Stat() (os.FileInfo, error) { +func (path pathImpl) Stat() (os.FileInfo, error) { file, err := os.Open(path.Path) if err != nil { @@ -24,7 +24,7 @@ func (path *Path) Stat() (os.FileInfo, error) { // File or dir exists -func (path *Path) Exists() bool { +func (path pathImpl) Exists() bool { if _, err := path.Stat(); os.IsNotExist(err) { return false } @@ -33,7 +33,7 @@ func (path *Path) Exists() bool { } // IsDir return true if path is dir -func (path *Path) IsDir() bool { +func (path pathImpl) IsDir() bool { stat, err := path.Stat() if err != nil { return false @@ -44,13 +44,13 @@ func (path *Path) IsDir() bool { // IsFile return true is path exists and not dir // (symlinks, devs, regular files) -func (path *Path) IsFile() bool { +func (path pathImpl) IsFile() bool { return path.Exists() && !path.IsDir() } // IsRegularFile return true if path is regular file // (wihtout devs, symlinks, ...) -func (path *Path) IsRegularFile() bool { +func (path pathImpl) IsRegularFile() bool { stat, err := path.Stat() if err != nil { return false diff --git a/struct.go b/struct.go index 824e057..75f3493 100644 --- a/struct.go +++ b/struct.go @@ -1,5 +1,5 @@ package pathutil -type Path struct { +type pathImpl struct { Path string } diff --git a/visit.go b/visit.go index 0d2a4cd..1a88d1f 100644 --- a/visit.go +++ b/visit.go @@ -5,13 +5,7 @@ import ( "path/filepath" ) -type VisitFunc func(path *Path) - -type VisitOpt struct { - Recurse bool -} - -func (path *Path) Visit(visitFunc VisitFunc, visitOpt VisitOpt) { +func (path pathImpl) Visit(visitFunc VisitFunc, visitOpt VisitOpt) { walkFn := func(file string, info os.FileInfo, err error) error { if info != nil && info.IsDir() && file != path.String() && !visitOpt.Recurse { return filepath.SkipDir diff --git a/visit_test.go b/visit_test.go index 9598782..db0b363 100644 --- a/visit_test.go +++ b/visit_test.go @@ -15,7 +15,7 @@ func TestVisitFlat(t *testing.T) { flat := make(map[string]int) path.Visit( - func(path *Path) { + func(path Path) { flat[path.String()] = 0 }, VisitOpt{}, @@ -41,7 +41,7 @@ func TestVisitRecurse(t *testing.T) { flat := make(map[string]int) path.Visit( - func(path *Path) { + func(path Path) { flat[path.String()] = 0 }, VisitOpt{Recurse: true}, From 59f1929ca280ebbc6c68ae1eedc026e368cf22f0 Mon Sep 17 00:00:00 2001 From: Jan Seidl Date: Fri, 27 Oct 2017 16:25:09 +0200 Subject: [PATCH 38/54] add Child, Children functions --- child.go | 26 ++++++++++++++++++++++++++ child_test.go | 45 +++++++++++++++++++++++++++++++++++++++++++++ interface.go | 3 +++ new.go | 9 ++++++--- new_test.go | 7 +++++-- 5 files changed, 85 insertions(+), 5 deletions(-) create mode 100644 child.go create mode 100644 child_test.go diff --git a/child.go b/child.go new file mode 100644 index 0000000..3afeb98 --- /dev/null +++ b/child.go @@ -0,0 +1,26 @@ +package pathutil + +import ( + "io/ioutil" +) + +func (path pathImpl) Child(childName ...string) (Path, error) { + pathChunks := append([]string{path.String()}, childName...) + + return NewPath(pathChunks...) +} + +func (path pathImpl) Children() ([]Path, error) { + files, err := ioutil.ReadDir(path.Canonpath()) + if err != nil { + return nil, err + } + + paths := make([]Path, len(files)) + for i, fileInfo := range files { + path, _ := NewPath(fileInfo.Name()) + paths[i] = path + } + + return paths, nil +} diff --git a/child_test.go b/child_test.go new file mode 100644 index 0000000..fec6f45 --- /dev/null +++ b/child_test.go @@ -0,0 +1,45 @@ +package pathutil + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestChild(t *testing.T) { + tempdir, err := NewTempDir(TempOpt{}) + assert.NoError(t, err) + + defer func() { + assert.NoError(t, tempdir.RemoveTree()) + }() + + kukPath, err := tempdir.Child("KUK", "PUK") + assert.NoError(t, err) + assert.NoError(t, kukPath.MakePath()) + + assert.True(t, kukPath.Exists()) +} + +func TestChildren(t *testing.T) { + tempdir, err := NewTempDir(TempOpt{}) + assert.NoError(t, err) + + defer func() { + assert.NoError(t, tempdir.RemoveTree()) + }() + + a, _ := tempdir.Child("a", "c") + a.MakePath() + b, _ := tempdir.Child("b") + b.MakePath() + + children, err := tempdir.Children() + assert.NoError(t, err) + + assert.Len(t, children, 2) + + exA, _ := NewPath("a") + exB, _ := NewPath("b") + assert.Equal(t, []Path{exA, exB}, children) +} diff --git a/interface.go b/interface.go index 0f287a4..7b92a54 100644 --- a/interface.go +++ b/interface.go @@ -53,4 +53,7 @@ type Path interface { Lines() ([]string, error) LinesWalker(LinesFunc) error + + Child(...string) (Path, error) + Children() ([]Path, error) } diff --git a/new.go b/new.go index 3ca2b86..1b72ae1 100644 --- a/new.go +++ b/new.go @@ -17,11 +17,14 @@ import ( func NewPath(path ...string) (Path, error) { newPath := pathImpl{} - joinPath := filepath.Join(path...) - if len(joinPath) == 0 { - return nil, errors.New("Paths requires defined, positive-lengths parts") + for index, pathChunk := range path { + if len(pathChunk) == 0 { + return nil, errors.Errorf("Paths requires defined, positive-lengths parts (part %d is empty", index) + } } + joinPath := filepath.Join(path...) + newPath.Path = strings.Replace(filepath.Clean(joinPath), "\\", "/", -1) return newPath, nil diff --git a/new_test.go b/new_test.go index eb798ea..ab8d92f 100644 --- a/new_test.go +++ b/new_test.go @@ -8,11 +8,14 @@ import ( func TestNewPath(t *testing.T) { path, err := NewPath("") assert.Nil(t, path) - assert.NotNil(t, err) + assert.Error(t, err) path, err = NewPath("test") assert.NotNil(t, path) - assert.Nil(t, err) + assert.NoError(t, err) + + _, err = NewPath("test", "") + assert.Error(t, err) } func TestNewTempFile(t *testing.T) { From f952bf31e7ca7b9bef417b49f165829322d18ce5 Mon Sep 17 00:00:00 2001 From: Jan Seidl Date: Fri, 27 Oct 2017 16:40:50 +0200 Subject: [PATCH 39/54] fix Children method --- child.go | 2 +- child_test.go | 4 ++-- new.go | 4 +++- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/child.go b/child.go index 3afeb98..6bf7e56 100644 --- a/child.go +++ b/child.go @@ -18,7 +18,7 @@ func (path pathImpl) Children() ([]Path, error) { paths := make([]Path, len(files)) for i, fileInfo := range files { - path, _ := NewPath(fileInfo.Name()) + path, _ := NewPath(path.Canonpath(), fileInfo.Name()) paths[i] = path } diff --git a/child_test.go b/child_test.go index fec6f45..6877dde 100644 --- a/child_test.go +++ b/child_test.go @@ -39,7 +39,7 @@ func TestChildren(t *testing.T) { assert.Len(t, children, 2) - exA, _ := NewPath("a") - exB, _ := NewPath("b") + exA, _ := NewPath(tempdir.String(), "a") + exB, _ := NewPath(tempdir.String(), "b") assert.Equal(t, []Path{exA, exB}, children) } diff --git a/new.go b/new.go index 1b72ae1..fcde7ea 100644 --- a/new.go +++ b/new.go @@ -9,11 +9,13 @@ import ( "github.com/pkg/errors" ) -// NewPath construct *Path +// NewPath construct Path // // for example // path := NewPath("/home/test", ".vimrc") // +// +// if you can use `Path` in `NewPath`, you must use `.String()` method func NewPath(path ...string) (Path, error) { newPath := pathImpl{} From 276a6b3b3e670177067a079ce41e0c2f30638e00 Mon Sep 17 00:00:00 2001 From: Jan Seidl Date: Sun, 29 Oct 2017 23:21:54 +0100 Subject: [PATCH 40/54] add Parent method --- interface.go | 2 ++ parent.go | 5 +++++ parent_test.go | 22 ++++++++++++++++++++++ 3 files changed, 29 insertions(+) create mode 100644 parent.go create mode 100644 parent_test.go diff --git a/interface.go b/interface.go index 7b92a54..ac0353e 100644 --- a/interface.go +++ b/interface.go @@ -56,4 +56,6 @@ type Path interface { Child(...string) (Path, error) Children() ([]Path, error) + + Parent() (Path, error) } diff --git a/parent.go b/parent.go new file mode 100644 index 0000000..7687cae --- /dev/null +++ b/parent.go @@ -0,0 +1,5 @@ +package pathutil + +func (path pathImpl) Parent() (Path, error) { + return NewPath(path.String(), "..") +} diff --git a/parent_test.go b/parent_test.go new file mode 100644 index 0000000..7f2b066 --- /dev/null +++ b/parent_test.go @@ -0,0 +1,22 @@ +package pathutil + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestParent(t *testing.T) { + temp, err := NewTempDir(TempOpt{}) + assert.NoError(t, err) + + parent, err := temp.Parent() + assert.NoError(t, err) + assert.Equal(t, "/tmp", parent.String()) + + root, err := NewPath("/") + assert.NoError(t, err) + parentOfRoot, err := root.Parent() + assert.NoError(t, err) + assert.Equal(t, "/", parentOfRoot.String()) +} From ebe422b35f00d59d8271532947ac7930da4a4bb1 Mon Sep 17 00:00:00 2001 From: Jan Seidl Date: Sun, 29 Oct 2017 23:29:55 +0100 Subject: [PATCH 41/54] * Parent method not return error * Parent doc --- interface.go | 2 +- parent.go | 11 +++++++++-- parent_test.go | 8 ++------ 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/interface.go b/interface.go index ac0353e..bb74296 100644 --- a/interface.go +++ b/interface.go @@ -57,5 +57,5 @@ type Path interface { Child(...string) (Path, error) Children() ([]Path, error) - Parent() (Path, error) + Parent() Path } diff --git a/parent.go b/parent.go index 7687cae..ed348fa 100644 --- a/parent.go +++ b/parent.go @@ -1,5 +1,12 @@ package pathutil -func (path pathImpl) Parent() (Path, error) { - return NewPath(path.String(), "..") +// path,_ := NewPath("foo/bar/baz"); parent := path.Parent() // foo/bar +// path,_ := NewPath("foo/wible.txt"); parent := path.Parent() // foo +// +// Returns a `Path` of corresponding to the parent directory of the +// original directory or file +func (path pathImpl) Parent() Path { + // path.String() can't be empty + parent, _ := NewPath(path.String(), "..") + return parent } diff --git a/parent_test.go b/parent_test.go index 7f2b066..ec4de07 100644 --- a/parent_test.go +++ b/parent_test.go @@ -10,13 +10,9 @@ func TestParent(t *testing.T) { temp, err := NewTempDir(TempOpt{}) assert.NoError(t, err) - parent, err := temp.Parent() - assert.NoError(t, err) - assert.Equal(t, "/tmp", parent.String()) + assert.Equal(t, "/tmp", temp.Parent().String()) root, err := NewPath("/") assert.NoError(t, err) - parentOfRoot, err := root.Parent() - assert.NoError(t, err) - assert.Equal(t, "/", parentOfRoot.String()) + assert.Equal(t, "/", root.Parent().String()) } From 9b57a08cc80f05fb17034ec5639a4427c1730340 Mon Sep 17 00:00:00 2001 From: Jan Seidl Date: Sat, 11 Nov 2017 00:24:08 +0100 Subject: [PATCH 42/54] add append methods --- append.go | 25 +++++++++++++++++++++++++ append_test.go | 24 ++++++++++++++++++++++++ interface.go | 4 ++++ open.go | 13 +++++++++++-- 4 files changed, 64 insertions(+), 2 deletions(-) create mode 100644 append.go create mode 100644 append_test.go diff --git a/append.go b/append.go new file mode 100644 index 0000000..ba3cc96 --- /dev/null +++ b/append.go @@ -0,0 +1,25 @@ +package pathutil + +import ( + "github.com/pkg/errors" +) + +func (path pathImpl) Append(data string) error { + return path.AppendBytes([]byte(data)) +} + +func (path pathImpl) AppendBytes(data []byte) (err error) { + file, err := path.OpenWriterAppend() + if err != nil { + return errors.Wrap(err, "Append open failed") + } + defer func() { + if e := file.Close(); e != nil { + err = errors.Wrap(e, "Append close failed") + } + }() + + _, err = file.Write(data) + + return errors.Wrap(err, "Append write failed") +} diff --git a/append_test.go b/append_test.go new file mode 100644 index 0000000..8ed93d9 --- /dev/null +++ b/append_test.go @@ -0,0 +1,24 @@ +package pathutil + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestAppend(t *testing.T) { + temp, err := NewTempFile(TempOpt{}) + assert.NoError(t, err) + + temp.Append("test\n") + + content, err := temp.Slurp() + assert.NoError(t, err) + assert.Equal(t, "test\n", content) + + temp.Append("test2") + + content, err = temp.Slurp() + assert.NoError(t, err) + assert.Equal(t, "test\ntest2", content) +} diff --git a/interface.go b/interface.go index bb74296..14c61cb 100644 --- a/interface.go +++ b/interface.go @@ -44,6 +44,7 @@ type Path interface { OpenReader() (io.Reader, *os.File, error) OpenWriter() (*os.File, error) + OpenWriterAppend() (*os.File, error) Slurp() (string, error) SlurpBytes() ([]byte, error) @@ -58,4 +59,7 @@ type Path interface { Children() ([]Path, error) Parent() Path + + Append(string) error + AppendBytes([]byte) error } diff --git a/open.go b/open.go index 8802122..d96a4f1 100644 --- a/open.go +++ b/open.go @@ -30,7 +30,7 @@ func (path pathImpl) OpenReader() (io.Reader, *os.File, error) { return bufio.NewReader(file), file, nil } -// OpenWriter retun *os.File +// OpenWriter retun *os.File as new file (like `>>`) // // for example: // path, _ := NewFilePath(FilePathOpt{}) @@ -46,7 +46,16 @@ func (path pathImpl) OpenReader() (io.Reader, *os.File, error) { // writer.Write(some_bytes) // func (path pathImpl) OpenWriter() (*os.File, error) { - file, err := os.OpenFile(path.String(), os.O_RDWR|os.O_CREATE, 0775) + return path.openWriterFlag(os.O_RDWR | os.O_CREATE) +} + +// OpenWriterAppend create new writer, similar as `OpenWriter` but append (like `>`) +func (path pathImpl) OpenWriterAppend() (*os.File, error) { + return path.openWriterFlag(os.O_APPEND | os.O_CREATE | os.O_WRONLY) +} + +func (path pathImpl) openWriterFlag(flag int) (*os.File, error) { + file, err := os.OpenFile(path.String(), flag, 0775) if err != nil { return nil, err } From 7a13c95e93eeac7f0a1983affad2c4dc31e9b9e7 Mon Sep 17 00:00:00 2001 From: Jan Seidl Date: Thu, 8 Feb 2018 23:08:59 +0100 Subject: [PATCH 43/54] refactor NewPath -> New OpenReader return io.ReadCloser only --- .gitignore | 2 + .godocdown.tmpl | 37 +++++ Gopkg.lock | 33 +++++ Makefile | 55 ++++++++ README.md | 194 +++++++++++++++++++++++++-- VERSION | 0 base_test.go | 22 +-- child.go | 4 +- child_test.go | 4 +- copy.go | 6 +- copy_test.go | 6 +- crypto.go | 4 +- examples/json_test.go | 8 +- examples/recursive_sha256sum_test.go | 2 +- examples/wc_test.go | 2 +- interface.go | 2 +- makepath_test.go | 2 +- new.go | 14 +- new_test.go | 8 +- open.go | 20 ++- open_test.go | 15 +-- parent.go | 6 +- parent_test.go | 2 +- rename.go | 2 +- stat_test.go | 28 ++-- test.sh | 12 -- visit.go | 2 +- visit_test.go | 4 +- 28 files changed, 392 insertions(+), 104 deletions(-) create mode 100644 .godocdown.tmpl create mode 100644 Gopkg.lock create mode 100644 Makefile create mode 100644 VERSION delete mode 100755 test.sh diff --git a/.gitignore b/.gitignore index daf913b..db171bc 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,5 @@ _testmain.go *.exe *.test *.prof + +coverage.txt diff --git a/.godocdown.tmpl b/.godocdown.tmpl new file mode 100644 index 0000000..8b5580d --- /dev/null +++ b/.godocdown.tmpl @@ -0,0 +1,37 @@ +# {{ .Name }} + +[![Release](https://img.shields.io/github/release/JaSei/pathutil-go.svg?style=flat-square)](https://github.com/JaSei/pathutil-go/releases/latest) +[![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square)](LICENSE.md) +[![Travis](https://img.shields.io/travis/JaSei/pathutil-go.svg?style=flat-square)](https://travis-ci.org/JaSei/pathutil-go) +[![Go Report Card](https://goreportcard.com/badge/github.com/JaSei/pathutil-go?style=flat-square)](https://goreportcard.com/report/github.com/JaSei/pathutil-go) +[![GoDoc](https://godoc.org/github.com/JaSei/pathutil-go?status.svg&style=flat-square)](http://godoc.org/github.com/JaSei/pathutil-go) +[![codecov.io](https://codecov.io/github/JaSei/pathutil-go/coverage.svg?branch=master)](https://codecov.io/github/JaSei/pathutil-go?branch=master) +[![Sourcegraph](https://sourcegraph.com/github.com/JaSei/pathutil-go/-/badge.svg)](https://sourcegraph.com/github.com/JaSei/pathutil-go?badge) + +{{ .EmitSynopsis }} + +{{ .EmitUsage }} + + +## Contributing + +Contributions are very much welcome. + +### Makefile + +Makefile provides several handy rules, like README.md `generator` , `setup` for prepare build/dev environment, `test`, `cover`, etc... + +Try `make help` for more information. + +### Before pull request + +please try: +* run tests (`make test`) +* run linter (`make lint`) +* if your IDE don't automaticaly do `go fmt`, run `go fmt` (`make fmt`) + +### README + +README.md are generate from template [.godocdown.tmpl](.godocdown.tmpl) and code documentation via [godocdown](https://github.com/robertkrimen/godocdown). + +Never edit README.md direct, because your change will be lost. diff --git a/Gopkg.lock b/Gopkg.lock new file mode 100644 index 0000000..dfd0ca9 --- /dev/null +++ b/Gopkg.lock @@ -0,0 +1,33 @@ +# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. + + +[[projects]] + name = "github.com/davecgh/go-spew" + packages = ["spew"] + revision = "346938d642f2ec3594ed81d874461961cd0faa76" + version = "v1.1.0" + +[[projects]] + name = "github.com/pkg/errors" + packages = ["."] + revision = "645ef00459ed84a119197bfb8d8205042c6df63d" + version = "v0.8.0" + +[[projects]] + name = "github.com/pmezard/go-difflib" + packages = ["difflib"] + revision = "792786c7400a136282c1664665ae0a8db921c6c2" + version = "v1.0.0" + +[[projects]] + name = "github.com/stretchr/testify" + packages = ["assert"] + revision = "69483b4bd14f5845b5a1e55bca19e954e827f1d0" + version = "v1.1.4" + +[solve-meta] + analyzer-name = "dep" + analyzer-version = 1 + inputs-digest = "6b7f5c88fcbf815c553a540e2f09c827ef51c4d9c9f744b1c7c882a12afbbfe8" + solver-name = "gps-cdcl" + solver-version = 1 diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..6de90d5 --- /dev/null +++ b/Makefile @@ -0,0 +1,55 @@ +HELP?=$$(go run main.go --help 2>&1) +VERSION?=$$(cat VERSION) + +setup: ## Install all the build and lint dependencies + go get -u github.com/alecthomas/gometalinter + go get -u github.com/golang/dep/cmd/dep + go get -u golang.org/x/tools/cmd/cover + dep ensure + gometalinter --install + go get -u github.com/robertkrimen/godocdown/godocdown + +generate: ## Generate README.md + godocdown >| README.md + +test: generate ## Run all the tests + echo 'mode: atomic' > coverage.txt && go list ./... | grep -v vendor | xargs -n1 -I{} sh -c 'go test -covermode=atomic -coverprofile=coverage.tmp {} && tail -n +2 coverage.tmp >> coverage.txt' && rm coverage.tmp + +cover: test ## Run all the tests and opens the coverage report + go tool cover -html=coverage.txt + +fmt: ## gofmt and goimports all go files + find . -name '*.go' -not -wholename './vendor/*' | while read -r file; do gofmt -w -s "$$file"; goimports -w "$$file"; done + +lint: ## Run all the linters + + #https://github.com/golang/go/issues/19490 + #--enable=vetshadow \ + + gometalinter --vendor --disable-all \ + --enable=deadcode \ + --enable=ineffassign \ + --enable=gosimple \ + --enable=staticcheck \ + --enable=gofmt \ + --enable=goimports \ + --enable=dupl \ + --enable=misspell \ + --enable=errcheck \ + --enable=vet \ + --deadline=10m \ + ./... + +ci: test lint ## Run all the tests and code checks + +build: ## Build the app + go build + +release: ## Release new version + git tag | grep -q $(VERSION) && echo This version was released! Increase VERSION! || git tag $(VERSION) && git push origin $(VERSION) + +# Absolutely awesome: http://marmelab.com/blog/2016/02/29/auto-documented-makefile.html +help: + @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' + +.DEFAULT_GOAL := build diff --git a/README.md b/README.md index 933812a..a42b213 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,188 @@ -# pathutil-go +# pathutil -[![Build Status](https://travis-ci.org/JaSei/pathutil-go.svg?branch=implementation)](https://travis-ci.org/JaSei/pathutil-go) -[![Build status](https://ci.appveyor.com/api/projects/status/urj0cf370sr5hjw4?svg=true)](https://ci.appveyor.com/project/JaSei/pathutil-go) -[![Go Report Card](https://goreportcard.com/badge/github.com/JaSei/pathutil-go)](https://goreportcard.com/report/github.com/JaSei/pathutil-go) -[![GoDoc](https://godoc.org/github.com/JaSei/pathutil-go?status.svg)](http://godoc.org/github.com/jasei/pathutil-go) -[![Sourcegraph](https://sourcegraph.com/github.com/jasei/pathutil-go/-/badge.svg)](https://sourcegraph.com/github.com/jasei/pathutil-go?badge) -[![codecov.io](https://codecov.io/github/boennemann/badges/coverage.svg?branch=implementation)](https://codecov.io/github/jasei/pathutil-go?branch=implementation) +[![Release](https://img.shields.io/github/release/JaSei/pathutil-go.svg?style=flat-square)](https://github.com/JaSei/pathutil-go/releases/latest) +[![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square)](LICENSE.md) +[![Travis](https://img.shields.io/travis/JaSei/pathutil-go.svg?style=flat-square)](https://travis-ci.org/JaSei/pathutil-go) +[![Go Report Card](https://goreportcard.com/badge/github.com/JaSei/pathutil-go?style=flat-square)](https://goreportcard.com/report/github.com/JaSei/pathutil-go) +[![GoDoc](https://godoc.org/github.com/JaSei/pathutil-go?status.svg&style=flat-square)](http://godoc.org/github.com/JaSei/pathutil-go) +[![codecov.io](https://codecov.io/github/JaSei/pathutil-go/coverage.svg?branch=master)](https://codecov.io/github/JaSei/pathutil-go?branch=master) +[![Sourcegraph](https://sourcegraph.com/github.com/JaSei/pathutil-go/-/badge.svg)](https://sourcegraph.com/github.com/JaSei/pathutil-go?badge) -File path utility inspired by David Golden's [Path::Tiny](https://metacpan.org/pod/Path::Tiny) + + +## Usage + +#### type CryptoHash + +```go +type CryptoHash struct { + hash.Hash +} +``` + + +#### func (*CryptoHash) BinSum + +```go +func (hash *CryptoHash) BinSum() []byte +``` +BinSum method is like hash.Sum(nil) + +#### func (*CryptoHash) HexSum + +```go +func (hash *CryptoHash) HexSum() string +``` +HexSum method retun hexstring representation of hash.Sum + +#### type LinesFunc + +```go +type LinesFunc func(string) +``` + + +#### type Path + +```go +type Path interface { + String() string + Canonpath() string + Basename() string + + Chdir() (Path, error) + Rename(string) (Path, error) + + Stat() (os.FileInfo, error) + + IsDir() bool + Exists() bool + IsFile() bool + IsRegularFile() bool + + Remove() error + RemoveTree() error + + Visit(VisitFunc, VisitOpt) + CopyFile(string) (Path, error) + + CopyFrom(io.Reader) (int64, error) + + Crypto(crypto.Hash) (*CryptoHash, error) + + MakePath() error + MakePathMode(os.FileMode) error + + OpenReader() (io.ReadCloser, error) + OpenWriter() (*os.File, error) + OpenWriterAppend() (*os.File, error) + + Slurp() (string, error) + SlurpBytes() ([]byte, error) + + Spew(string) error + SpewBytes([]byte) error + + Lines() ([]string, error) + LinesWalker(LinesFunc) error + + Child(...string) (Path, error) + Children() ([]Path, error) + + Parent() Path + + Append(string) error + AppendBytes([]byte) error +} +``` + + +#### func Cwd + +```go +func Cwd() (Path, error) +``` +Cwd create new path from current working directory + +#### func New + +```go +func New(path ...string) (Path, error) +``` +New construct Path + +for example + + path := New("/home/test", ".vimrc") + +if you can use `Path` in `New`, you must use `.String()` method + +#### func NewTempDir + +```go +func NewTempDir(options TempOpt) (Path, error) +``` +NewTempDir create temp directory + +for cleanup use `defer` + + tempdir, err := pathutil.NewTempDir(TempOpt{}) + defer tempdir.RemoveTree() + +#### func NewTempFile + +```go +func NewTempFile(options TempOpt) (Path, error) +``` + +#### type TempOpt + +```go +type TempOpt struct { + // directory where is temp file/dir create, empty string `""` (default) means TEMPDIR (`os.TempDir`) + Dir string + // name beginning with prefix + Prefix string +} +``` + +TempOpt is struct for configure new tempdir or tempfile + +#### type VisitFunc + +```go +type VisitFunc func(path Path) +``` + + +#### type VisitOpt + +```go +type VisitOpt struct { + Recurse bool +} +``` + + +## Contributing + +Contributions are very much welcome. + +### Makefile + +Makefile provides several handy rules, like README.md `generator` , `setup` for prepare build/dev environment, `test`, `cover`, etc... + +Try `make help` for more information. + +### Before pull request + +please try: +* run tests (`make test`) +* run linter (`make lint`) +* if your IDE don't automaticaly do `go fmt`, run `go fmt` (`make fmt`) + +### README + +README.md are generate from template [.godocdown.tmpl](.godocdown.tmpl) and code documentation via [godocdown](https://github.com/robertkrimen/godocdown). + +Never edit README.md direct, because your change will be lost. diff --git a/VERSION b/VERSION new file mode 100644 index 0000000..e69de29 diff --git a/base_test.go b/base_test.go index 2eab929..b6cfdce 100644 --- a/base_test.go +++ b/base_test.go @@ -9,40 +9,40 @@ import ( ) func TestString(t *testing.T) { - path, _ := NewPath("tmp/test") + path, _ := New("tmp/test") assert.Equal(t, "tmp/test", path.String(), "string") - path, _ = NewPath("tmp/test/") + path, _ = New("tmp/test/") assert.Equal(t, "tmp/test", path.String(), "string") - path, _ = NewPath("tmp", "test") + path, _ = New("tmp", "test") assert.Equal(t, "tmp/test", path.String(), "string") } func TestCanonpath(t *testing.T) { - path, _ := NewPath("tmp/test") + path, _ := New("tmp/test") assert.Equal(t, fmt.Sprintf("tmp%stest", string(filepath.Separator)), path.Canonpath(), "linux rel path") - path, _ = NewPath("tmp/test/") + path, _ = New("tmp/test/") assert.Equal(t, fmt.Sprintf("tmp%stest", string(filepath.Separator)), path.Canonpath(), "linux rel path with end slash") - path, _ = NewPath("tmp", "test") + path, _ = New("tmp", "test") assert.Equal(t, fmt.Sprintf("tmp%stest", string(filepath.Separator)), path.Canonpath(), "more paths elemets") - path, _ = NewPath("tmp\\test") + path, _ = New("tmp\\test") assert.Equal(t, fmt.Sprintf("tmp%stest", string(filepath.Separator)), path.Canonpath(), "windows rel path") } func TestBasename(t *testing.T) { - path, _ := NewPath("/tmp/test") + path, _ := New("/tmp/test") assert.Equal(t, "test", path.Basename(), "basename of /tmp/test") - path, _ = NewPath("/") + path, _ = New("/") assert.Equal(t, "", path.Basename(), "basename of root") - path, _ = NewPath("relative") + path, _ = New("relative") assert.Equal(t, "relative", path.Basename(), "relative basename") - path, _ = NewPath("relative/a") + path, _ = New("relative/a") assert.Equal(t, "a", path.Basename(), "relative subpath basename") } diff --git a/child.go b/child.go index 6bf7e56..0b0d481 100644 --- a/child.go +++ b/child.go @@ -7,7 +7,7 @@ import ( func (path pathImpl) Child(childName ...string) (Path, error) { pathChunks := append([]string{path.String()}, childName...) - return NewPath(pathChunks...) + return New(pathChunks...) } func (path pathImpl) Children() ([]Path, error) { @@ -18,7 +18,7 @@ func (path pathImpl) Children() ([]Path, error) { paths := make([]Path, len(files)) for i, fileInfo := range files { - path, _ := NewPath(path.Canonpath(), fileInfo.Name()) + path, _ := New(path.Canonpath(), fileInfo.Name()) paths[i] = path } diff --git a/child_test.go b/child_test.go index 6877dde..61fd3d4 100644 --- a/child_test.go +++ b/child_test.go @@ -39,7 +39,7 @@ func TestChildren(t *testing.T) { assert.Len(t, children, 2) - exA, _ := NewPath(tempdir.String(), "a") - exB, _ := NewPath(tempdir.String(), "b") + exA, _ := New(tempdir.String(), "a") + exB, _ := New(tempdir.String(), "b") assert.Equal(t, []Path{exA, exB}, children) } diff --git a/copy.go b/copy.go index 3aa6212..de67a36 100644 --- a/copy.go +++ b/copy.go @@ -6,13 +6,13 @@ import ( ) func (srcPath pathImpl) CopyFile(dst string) (Path, error) { - dstPath, err := NewPath(dst) + dstPath, err := New(dst) if err != nil { return nil, err } if dstPath.IsDir() { - dstPath, err := NewPath(dst, srcPath.Basename()) + dstPath, err := New(dst, srcPath.Basename()) if err != nil { return nil, err } else { @@ -44,5 +44,5 @@ func (srcPath pathImpl) CopyFile(dst string) (Path, error) { return nil, err } - return NewPath(dst) + return New(dst) } diff --git a/copy_test.go b/copy_test.go index 4ea6ef1..7e1468c 100644 --- a/copy_test.go +++ b/copy_test.go @@ -7,7 +7,7 @@ import ( ) func TestCopyFileDstFileExists(t *testing.T) { - src, _ := NewPath("copy_test.go") + src, _ := New("copy_test.go") dst, err := NewTempFile(TempOpt{}) assert.Nil(t, err) defer dst.Remove() @@ -23,8 +23,8 @@ func TestCopyFileDstFileExists(t *testing.T) { } func TestCopyFileDstIsDir(t *testing.T) { - src, _ := NewPath("copy_test.go") - dst, _ := NewPath(os.TempDir()) + src, _ := New("copy_test.go") + dst, _ := New(os.TempDir()) assert.Exactly(t, true, dst.Exists(), "dst dir exists") newDst, err := src.CopyFile(dst.String()) diff --git a/crypto.go b/crypto.go index a1069c4..5bd1606 100644 --- a/crypto.go +++ b/crypto.go @@ -15,11 +15,11 @@ import ( // fmt.Println(hash.HexSum()) func (path pathImpl) Crypto(hash crypto.Hash) (*CryptoHash, error) { - reader, file, err := path.OpenReader() + reader, err := path.OpenReader() if err != nil { return nil, err } - defer file.Close() + defer reader.Close() h := hash.New() diff --git a/examples/json_test.go b/examples/json_test.go index 237cac2..36ce7bd 100644 --- a/examples/json_test.go +++ b/examples/json_test.go @@ -26,13 +26,13 @@ var expected = FileInfo{ } func TestLoadJsonViaReader(t *testing.T) { - path, err := pathutil.NewPath("example.json") + path, err := pathutil.New("example.json") assert.Nil(t, err) - reader, file, err := path.OpenReader() + reader, err := path.OpenReader() assert.Nil(t, err) defer func() { - assert.Nil(t, file.Close()) + assert.Nil(t, reader.Close()) }() assert.NotNil(t, reader) @@ -47,7 +47,7 @@ func TestLoadJsonViaReader(t *testing.T) { } func TestLoadJsonViaSlurp(t *testing.T) { - path, err := pathutil.NewPath("example.json") + path, err := pathutil.New("example.json") assert.Nil(t, err) jsonBytes, err := path.SlurpBytes() diff --git a/examples/recursive_sha256sum_test.go b/examples/recursive_sha256sum_test.go index 1cb8dde..0a6d50e 100644 --- a/examples/recursive_sha256sum_test.go +++ b/examples/recursive_sha256sum_test.go @@ -9,7 +9,7 @@ import ( ) func TestVisitRecursiveAndHashAllFiles(t *testing.T) { - path, err := pathutil.NewPath("tree") + path, err := pathutil.New("tree") assert.Nil(t, err) path.Visit( diff --git a/examples/wc_test.go b/examples/wc_test.go index 99ba657..37652d1 100644 --- a/examples/wc_test.go +++ b/examples/wc_test.go @@ -25,7 +25,7 @@ func wc(path pathutil.Path) (lines, words, chars int) { } func Test(t *testing.T) { - path, err := pathutil.NewPath("../LICENSE") + path, err := pathutil.New("../LICENSE") assert.Nil(t, err) diff --git a/interface.go b/interface.go index 14c61cb..229ca38 100644 --- a/interface.go +++ b/interface.go @@ -42,7 +42,7 @@ type Path interface { MakePath() error MakePathMode(os.FileMode) error - OpenReader() (io.Reader, *os.File, error) + OpenReader() (io.ReadCloser, error) OpenWriter() (*os.File, error) OpenWriterAppend() (*os.File, error) diff --git a/makepath_test.go b/makepath_test.go index 38d3a79..7940367 100644 --- a/makepath_test.go +++ b/makepath_test.go @@ -14,7 +14,7 @@ func TestMakePath(t *testing.T) { assert.NoError(t, tempdir.RemoveTree()) }() - newPath, err := NewPath(tempdir.String(), "a/b/c") + newPath, err := New(tempdir.String(), "a/b/c") assert.NoError(t, err) assert.False(t, newPath.Exists()) diff --git a/new.go b/new.go index fcde7ea..21cfc78 100644 --- a/new.go +++ b/new.go @@ -9,14 +9,14 @@ import ( "github.com/pkg/errors" ) -// NewPath construct Path +// New construct Path // // for example -// path := NewPath("/home/test", ".vimrc") +// path := New("/home/test", ".vimrc") // // -// if you can use `Path` in `NewPath`, you must use `.String()` method -func NewPath(path ...string) (Path, error) { +// if you can use `Path` in `New`, you must use `.String()` method +func New(path ...string) (Path, error) { newPath := pathImpl{} for index, pathChunk := range path { @@ -59,7 +59,7 @@ func NewTempFile(options TempOpt) (Path, error) { defer file.Close() - return NewPath(file.Name()) + return New(file.Name()) } // NewTempDir create temp directory @@ -73,7 +73,7 @@ func NewTempDir(options TempOpt) (Path, error) { return nil, errors.Wrapf(err, "NewTempDir(%+v) fail", options) } - return NewPath(dir) + return New(dir) } // Cwd create new path from current working directory @@ -83,5 +83,5 @@ func Cwd() (Path, error) { return nil, errors.Wrap(err, "Getwd fail") } - return NewPath(cwd) + return New(cwd) } diff --git a/new_test.go b/new_test.go index ab8d92f..e76bf12 100644 --- a/new_test.go +++ b/new_test.go @@ -5,16 +5,16 @@ import ( "testing" ) -func TestNewPath(t *testing.T) { - path, err := NewPath("") +func TestNew(t *testing.T) { + path, err := New("") assert.Nil(t, path) assert.Error(t, err) - path, err = NewPath("test") + path, err = New("test") assert.NotNil(t, path) assert.NoError(t, err) - _, err = NewPath("test", "") + _, err = New("test", "") assert.Error(t, err) } diff --git a/open.go b/open.go index d96a4f1..f2c89ab 100644 --- a/open.go +++ b/open.go @@ -9,25 +9,23 @@ import ( "github.com/pkg/errors" ) -// OpenReader retun bufio io.Reader -// because bufio io.Reader don't implement Close method, -// OpenReader returns *os.File too +// OpenReader retun io.ReaderCloser // // for example: -// path, _ := NewPath("/bla/bla") -// reader, file, err := path.OpenReader() +// path, _ := New("/bla/bla") +// r, err := path.OpenReader() // if err != nil { // panic(err) // } -// defer file.Close() +// defer r.Close() // -func (path pathImpl) OpenReader() (io.Reader, *os.File, error) { +func (path pathImpl) OpenReader() (io.ReadCloser, error) { file, err := os.Open(path.Canonpath()) if err != nil { - return nil, nil, errors.Wrapf(err, "OpenReader on path %s fail (%+v)", path, path) + return nil, errors.Wrapf(err, "OpenReader on path %s fail (%+v)", path, path) } - return bufio.NewReader(file), file, nil + return file, nil } // OpenWriter retun *os.File as new file (like `>>`) @@ -127,11 +125,11 @@ func (path pathImpl) SpewBytes(bytes []byte) error { // lines = append(lines, line) // }) func (path pathImpl) LinesWalker(linesFunc LinesFunc) error { - reader, file, err := path.OpenReader() + reader, err := path.OpenReader() if err != nil { return err } - defer file.Close() + defer reader.Close() scanner := bufio.NewScanner(reader) diff --git a/open_test.go b/open_test.go index bdfc6df..6be3151 100644 --- a/open_test.go +++ b/open_test.go @@ -1,25 +1,22 @@ package pathutil import ( - "bufio" "github.com/stretchr/testify/assert" "testing" ) func TestOpenReader(t *testing.T) { - path, err := NewPath("open.go") + path, err := New("open.go") assert.Nil(t, err) - reader, file, err := path.OpenReader() + reader, err := path.OpenReader() assert.Nil(t, err) - defer file.Close() - - assert.IsType(t, new(bufio.Reader), reader) + defer reader.Close() } func TestSlurp(t *testing.T) { - path, err := NewPath("./LICENSE") + path, err := New("./LICENSE") assert.Nil(t, err) @@ -29,7 +26,7 @@ func TestSlurp(t *testing.T) { } func TestLinesWalker(t *testing.T) { - path, err := NewPath("./LICENSE") + path, err := New("./LICENSE") assert.Nil(t, err) @@ -43,7 +40,7 @@ func TestLinesWalker(t *testing.T) { } func TestLines(t *testing.T) { - path, err := NewPath("./LICENSE") + path, err := New("./LICENSE") assert.Nil(t, err) diff --git a/parent.go b/parent.go index ed348fa..2d75683 100644 --- a/parent.go +++ b/parent.go @@ -1,12 +1,12 @@ package pathutil -// path,_ := NewPath("foo/bar/baz"); parent := path.Parent() // foo/bar -// path,_ := NewPath("foo/wible.txt"); parent := path.Parent() // foo +// path,_ := New("foo/bar/baz"); parent := path.Parent() // foo/bar +// path,_ := New("foo/wible.txt"); parent := path.Parent() // foo // // Returns a `Path` of corresponding to the parent directory of the // original directory or file func (path pathImpl) Parent() Path { // path.String() can't be empty - parent, _ := NewPath(path.String(), "..") + parent, _ := New(path.String(), "..") return parent } diff --git a/parent_test.go b/parent_test.go index ec4de07..bf69bd2 100644 --- a/parent_test.go +++ b/parent_test.go @@ -12,7 +12,7 @@ func TestParent(t *testing.T) { assert.Equal(t, "/tmp", temp.Parent().String()) - root, err := NewPath("/") + root, err := New("/") assert.NoError(t, err) assert.Equal(t, "/", root.Parent().String()) } diff --git a/rename.go b/rename.go index 1aaeaa8..33f7a30 100644 --- a/rename.go +++ b/rename.go @@ -6,7 +6,7 @@ import ( // Rename path to new path func (old pathImpl) Rename(new string) (Path, error) { - newPath, err := NewPath(new) + newPath, err := New(new) if err != nil { return nil, err } diff --git a/stat_test.go b/stat_test.go index cd8d859..4bedea7 100644 --- a/stat_test.go +++ b/stat_test.go @@ -8,37 +8,37 @@ import ( ) func TestExists(t *testing.T) { - path, _ := NewPath("stat_test.go") + path, _ := New("stat_test.go") assert.Exactly(t, true, path.Exists(), "file exists") - path, _ = NewPath("/sdlkfjsflsjfsl") + path, _ = New("/sdlkfjsflsjfsl") assert.Exactly(t, false, path.Exists(), "wired root dir don't exists") - path, _ = NewPath(os.TempDir()) + path, _ = New(os.TempDir()) assert.Exactly(t, true, path.Exists(), "home dir exists") } func TestIsDir(t *testing.T) { - path, _ := NewPath(os.TempDir()) + path, _ := New(os.TempDir()) assert.Exactly(t, true, path.IsDir(), "temp dir is dir") - path, _ = NewPath("stat_test.go") + path, _ = New("stat_test.go") assert.Exactly(t, false, path.IsDir(), "this test file isn't dir") - path, _ = NewPath("/safjasfjalfja") + path, _ = New("/safjasfjalfja") assert.Exactly(t, false, path.IsDir(), "unexists somethings isn't dir") } func TestIsFile(t *testing.T) { - path, _ := NewPath(os.TempDir()) + path, _ := New(os.TempDir()) assert.Exactly(t, false, path.IsFile(), "temp dir is dir - no file") - path, _ = NewPath("stat_test.go") + path, _ = New("stat_test.go") assert.Exactly(t, true, path.IsFile(), "this test file is file") - path, _ = NewPath("/safjasfjalfja") + path, _ = New("/safjasfjalfja") assert.Exactly(t, false, path.IsFile(), "unexists something isn't file") if runtime.GOOS != "windows" { - path, _ = NewPath("/dev/zero") + path, _ = New("/dev/zero") assert.Exactly(t, true, path.IsFile(), "/dev/zero is file") } @@ -46,16 +46,16 @@ func TestIsFile(t *testing.T) { } func TestIsRegularFile(t *testing.T) { - path, _ := NewPath(os.TempDir()) + path, _ := New(os.TempDir()) assert.Exactly(t, false, path.IsRegularFile(), "temp dir is dir - no file") - path, _ = NewPath("stat_test.go") + path, _ = New("stat_test.go") assert.Exactly(t, true, path.IsRegularFile(), "this test file is file") - path, _ = NewPath("/safjasfjalfja") + path, _ = New("/safjasfjalfja") assert.Exactly(t, false, path.IsRegularFile(), "unexists something isn't file") - path, _ = NewPath("/dev/zero") + path, _ = New("/dev/zero") assert.Exactly(t, false, path.IsRegularFile(), "/dev/zero isn't regular file file") //symlink test diff --git a/test.sh b/test.sh deleted file mode 100755 index 88c4e8b..0000000 --- a/test.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env bash - -set -e -echo "" > coverage.txt - -for d in $(go list ./... | grep -v vendor); do - go test -v -race -coverprofile=profile.out -covermode=atomic $d - if [ -f profile.out ]; then - cat profile.out >> coverage.txt - rm profile.out - fi -done diff --git a/visit.go b/visit.go index 1a88d1f..cdc0cd3 100644 --- a/visit.go +++ b/visit.go @@ -20,7 +20,7 @@ func (path pathImpl) Visit(visitFunc VisitFunc, visitOpt VisitOpt) { return nil } - path, err := NewPath(file) + path, err := New(file) visitFunc(path) diff --git a/visit_test.go b/visit_test.go index db0b363..ef0c1f2 100644 --- a/visit_test.go +++ b/visit_test.go @@ -6,7 +6,7 @@ import ( ) func TestVisitFlat(t *testing.T) { - path, err := NewPath("examples/tree") + path, err := New("examples/tree") assert.Nil(t, err) flat_expected := map[string]int{ @@ -25,7 +25,7 @@ func TestVisitFlat(t *testing.T) { } func TestVisitRecurse(t *testing.T) { - path, err := NewPath("examples/tree") + path, err := New("examples/tree") assert.Nil(t, err) From 10a1679cc345317ec214d64bb3558e2ce8c6e9d3 Mon Sep 17 00:00:00 2001 From: Jan Seidl Date: Thu, 8 Feb 2018 23:56:10 +0100 Subject: [PATCH 44/54] improve documentation --- README.md | 313 ++++++++++++++++++++++++++++++++++++++ append.go | 4 +- base.go | 14 +- chdir.go | 2 +- child.go | 4 +- copy.go | 2 +- crypto.go | 2 +- examples/download_test.go | 5 +- makepath.go | 4 +- new.go | 4 +- open.go | 22 +-- parent.go | 2 +- remove.go | 6 +- rename.go | 2 +- stat.go | 12 +- struct.go | 5 +- visit.go | 2 +- 17 files changed, 360 insertions(+), 45 deletions(-) diff --git a/README.md b/README.md index a42b213..4eb8097 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,48 @@ [![codecov.io](https://codecov.io/github/JaSei/pathutil-go/coverage.svg?branch=master)](https://codecov.io/github/JaSei/pathutil-go?branch=master) [![Sourcegraph](https://sourcegraph.com/github.com/JaSei/pathutil-go/-/badge.svg)](https://sourcegraph.com/github.com/JaSei/pathutil-go?badge) +Pathutil is I/O utility primary inspired by David Golden's +[Path::Tiny](https://metacpan.org/pod/Path::Tiny). It is friendlier to use than +[path](https://golang.org/pkg/path/), +[filepath](https://golang.org/pkg/path/filepath/) and provides many of other +functions which isn't in core libraries (like `Copy` for example) +### SYNOPSIS + + import ( + "fmt" + "github.com/JaSei/pathutil-go" + ) + + // creating pathutil objects + dir, _ := pathutil.New("/tmp") + foo, _ := pathutil.New("foo.txt") + + subdir, _ := dir.Child("foo") + bar, _ := subdir.Child("bar.txt") + + // stringifies as cleaned up path + file, _ := pathutil.New("./foo.txt") + fmt.Println(file) // "foo.txt" + + // reading files + guts, _ := file.Slurp() + lines, _ := file.Lines() + + // writing files + bar.Spew(data) + + // reading directories + children, _ := dir.Children() + for _, child := range children { + } + + +### SEE ALSO + +* [Path::Tiny](https://metacpan.org/pod/Path::Tiny) for Perl * [better +files](https://github.com/pathikrit/better-files) for Scala * +[pathlib](https://docs.python.org/3/library/pathlib.html) for python ## Usage @@ -135,6 +176,278 @@ for cleanup use `defer` func NewTempFile(options TempOpt) (Path, error) ``` +#### type PathImpl + +```go +type PathImpl struct { +} +``` + +type PathImpl implements Path interface + +#### func (PathImpl) Append + +```go +func (path PathImpl) Append(data string) error +``` + +#### func (PathImpl) AppendBytes + +```go +func (path PathImpl) AppendBytes(data []byte) (err error) +``` + +#### func (PathImpl) Basename + +```go +func (path PathImpl) Basename() string +``` +Basename like path/filepath.Base + +#### func (PathImpl) Canonpath + +```go +func (path PathImpl) Canonpath() string +``` +Canonpath retrun path with right os separator + +#### func (PathImpl) Chdir + +```go +func (path PathImpl) Chdir() (Path, error) +``` +Chdir change current working directory do the path and return old current +working directory + +#### func (PathImpl) Child + +```go +func (path PathImpl) Child(childName ...string) (Path, error) +``` + +#### func (PathImpl) Children + +```go +func (path PathImpl) Children() ([]Path, error) +``` + +#### func (PathImpl) CopyFile + +```go +func (srcPath PathImpl) CopyFile(dst string) (Path, error) +``` + +#### func (PathImpl) CopyFrom + +```go +func (path PathImpl) CopyFrom(reader io.Reader) (int64, error) +``` +CopyFrom copy stream from reader to path (file after copy close and sync) + +#### func (PathImpl) Crypto + +```go +func (path PathImpl) Crypto(hash crypto.Hash) (*CryptoHash, error) +``` + +#### func (PathImpl) Exists + +```go +func (path PathImpl) Exists() bool +``` + +#### func (PathImpl) IsDir + +```go +func (path PathImpl) IsDir() bool +``` +IsDir return true if path is dir + +#### func (PathImpl) IsFile + +```go +func (path PathImpl) IsFile() bool +``` +IsFile return true is path exists and not dir (symlinks, devs, regular files) + +#### func (PathImpl) IsRegularFile + +```go +func (path PathImpl) IsRegularFile() bool +``` +IsRegularFile return true if path is regular file (wihtout devs, symlinks, ...) + +#### func (PathImpl) Lines + +```go +func (path PathImpl) Lines() ([]string, error) +``` +Read all lines and return as array of lines + +#### func (PathImpl) LinesWalker + +```go +func (path PathImpl) LinesWalker(linesFunc LinesFunc) error +``` +LinesWalker read lines in file and call LinesFunc with line parameter + +for example: + + lines := make([]string, 0) + + linesFuncError := path.LinesWalker(func(line string) { + lines = append(lines, line) + }) + +#### func (PathImpl) MakePath + +```go +func (path PathImpl) MakePath() error +``` +Make path create directory(ies) in path if not exists (like `mkdir -p`) with +default 0777 mode if you need set mode, use `MakePathMode` + +#### func (PathImpl) MakePathMode + +```go +func (path PathImpl) MakePathMode(mode os.FileMode) error +``` +Make path create directory(ies) in path if not exists (like `mkdir -p`) with +default given mode + +#### func (PathImpl) OpenReader + +```go +func (path PathImpl) OpenReader() (io.ReadCloser, error) +``` +OpenReader retun io.ReaderCloser + +for example: + + path, _ := New("/bla/bla") + r, err := path.OpenReader() + if err != nil { + panic(err) + } + defer r.Close() + +#### func (PathImpl) OpenWriter + +```go +func (path PathImpl) OpenWriter() (*os.File, error) +``` +OpenWriter retun *os.File as new file (like `>>`) + +for example: + + path, _ := NewFilePath(FilePathOpt{}) + file, err := path.OpenWriter() + if err != nil { + panic(err) + } + defer func(){ + file.Close() + file.Sync() + }() + + writer.Write(some_bytes) + +#### func (PathImpl) OpenWriterAppend + +```go +func (path PathImpl) OpenWriterAppend() (*os.File, error) +``` +OpenWriterAppend create new writer, similar as `OpenWriter` but append (like +`>`) + +#### func (PathImpl) Parent + +```go +func (path PathImpl) Parent() Path +``` + + path,_ := New("foo/bar/baz"); parent := path.Parent() // foo/bar + path,_ := New("foo/wible.txt"); parent := path.Parent() // foo +Returns a `Path` of corresponding to the parent directory of the original +directory or file + +#### func (PathImpl) Remove + +```go +func (path PathImpl) Remove() error +``` +Remove file + + err := path.Remove() + +like os.Remove + +#### func (PathImpl) RemoveTree + +```go +func (path PathImpl) RemoveTree() error +``` +Remove tree of directory(ies) include files + + err := path.RemoveTree + +like os.RemoveAll + +#### func (PathImpl) Rename + +```go +func (old PathImpl) Rename(new string) (Path, error) +``` +Rename path to new path + +#### func (PathImpl) Slurp + +```go +func (path PathImpl) Slurp() (string, error) +``` +Slurp read all file like ioutil.ReadFile + +#### func (PathImpl) SlurpBytes + +```go +func (path PathImpl) SlurpBytes() ([]byte, error) +``` + +#### func (PathImpl) Spew + +```go +func (path PathImpl) Spew(content string) error +``` +Spew write string to file + +#### func (PathImpl) SpewBytes + +```go +func (path PathImpl) SpewBytes(bytes []byte) error +``` +SpewBytes write bytes to file + +#### func (PathImpl) Stat + +```go +func (path PathImpl) Stat() (os.FileInfo, error) +``` +Stat return os.FileInfo + +#### func (PathImpl) String + +```go +func (path PathImpl) String() string +``` +String return stable string representation of path this representation is linux +like (slash as separator) for os specific string use Canonpath method + +#### func (PathImpl) Visit + +```go +func (path PathImpl) Visit(visitFunc VisitFunc, visitOpt VisitOpt) +``` + #### type TempOpt ```go diff --git a/append.go b/append.go index ba3cc96..c47ae19 100644 --- a/append.go +++ b/append.go @@ -4,11 +4,11 @@ import ( "github.com/pkg/errors" ) -func (path pathImpl) Append(data string) error { +func (path PathImpl) Append(data string) error { return path.AppendBytes([]byte(data)) } -func (path pathImpl) AppendBytes(data []byte) (err error) { +func (path PathImpl) AppendBytes(data []byte) (err error) { file, err := path.OpenWriterAppend() if err != nil { return errors.Wrap(err, "Append open failed") diff --git a/base.go b/base.go index db498f8..67a2f9d 100644 --- a/base.go +++ b/base.go @@ -7,21 +7,21 @@ import ( // String return stable string representation of path // this representation is linux like (slash as separator) // for os specific string use Canonpath method -func (path pathImpl) String() string { - return path.Path +func (path PathImpl) String() string { + return path.path } // Canonpath retrun path with right os separator -func (path pathImpl) Canonpath() string { - return filepath.FromSlash(filepath.Clean(path.Path)) +func (path PathImpl) Canonpath() string { + return filepath.FromSlash(filepath.Clean(path.path)) } // Basename // like path/filepath.Base -func (path pathImpl) Basename() string { - if path.Path == "/" { +func (path PathImpl) Basename() string { + if path.path == "/" { return "" } - return filepath.Base(path.Path) + return filepath.Base(path.path) } diff --git a/chdir.go b/chdir.go index 5f9a2d6..110d30f 100644 --- a/chdir.go +++ b/chdir.go @@ -7,7 +7,7 @@ import ( ) // Chdir change current working directory do the path and return old current working directory -func (path pathImpl) Chdir() (Path, error) { +func (path PathImpl) Chdir() (Path, error) { oldPath, err := Cwd() if err != nil { return nil, errors.Wrap(err, "Cwd fail") diff --git a/child.go b/child.go index 0b0d481..2ed660a 100644 --- a/child.go +++ b/child.go @@ -4,13 +4,13 @@ import ( "io/ioutil" ) -func (path pathImpl) Child(childName ...string) (Path, error) { +func (path PathImpl) Child(childName ...string) (Path, error) { pathChunks := append([]string{path.String()}, childName...) return New(pathChunks...) } -func (path pathImpl) Children() ([]Path, error) { +func (path PathImpl) Children() ([]Path, error) { files, err := ioutil.ReadDir(path.Canonpath()) if err != nil { return nil, err diff --git a/copy.go b/copy.go index de67a36..ccfd1fc 100644 --- a/copy.go +++ b/copy.go @@ -5,7 +5,7 @@ import ( "os" ) -func (srcPath pathImpl) CopyFile(dst string) (Path, error) { +func (srcPath PathImpl) CopyFile(dst string) (Path, error) { dstPath, err := New(dst) if err != nil { return nil, err diff --git a/crypto.go b/crypto.go index 5bd1606..53ca2df 100644 --- a/crypto.go +++ b/crypto.go @@ -14,7 +14,7 @@ import ( // hash, err := path.Crypto(crypto.SHA256) // fmt.Println(hash.HexSum()) -func (path pathImpl) Crypto(hash crypto.Hash) (*CryptoHash, error) { +func (path PathImpl) Crypto(hash crypto.Hash) (*CryptoHash, error) { reader, err := path.OpenReader() if err != nil { return nil, err diff --git a/examples/download_test.go b/examples/download_test.go index 03db52a..aeae415 100644 --- a/examples/download_test.go +++ b/examples/download_test.go @@ -1,10 +1,11 @@ package pathutil_test import ( - "github.com/JaSei/pathutil-go" - "github.com/stretchr/testify/assert" "net/http" "testing" + + "github.com/JaSei/pathutil-go" + "github.com/stretchr/testify/assert" ) func TestDownload(t *testing.T) { diff --git a/makepath.go b/makepath.go index c20ddbd..f612adc 100644 --- a/makepath.go +++ b/makepath.go @@ -6,11 +6,11 @@ import ( // Make path create directory(ies) in path if not exists (like `mkdir -p`) with default 0777 mode // if you need set mode, use `MakePathMode` -func (path pathImpl) MakePath() error { +func (path PathImpl) MakePath() error { return path.MakePathMode(0777) } // Make path create directory(ies) in path if not exists (like `mkdir -p`) with default given mode -func (path pathImpl) MakePathMode(mode os.FileMode) error { +func (path PathImpl) MakePathMode(mode os.FileMode) error { return os.MkdirAll(path.Canonpath(), mode) } diff --git a/new.go b/new.go index 21cfc78..74a090d 100644 --- a/new.go +++ b/new.go @@ -17,7 +17,7 @@ import ( // // if you can use `Path` in `New`, you must use `.String()` method func New(path ...string) (Path, error) { - newPath := pathImpl{} + newPath := PathImpl{} for index, pathChunk := range path { if len(pathChunk) == 0 { @@ -27,7 +27,7 @@ func New(path ...string) (Path, error) { joinPath := filepath.Join(path...) - newPath.Path = strings.Replace(filepath.Clean(joinPath), "\\", "/", -1) + newPath.path = strings.Replace(filepath.Clean(joinPath), "\\", "/", -1) return newPath, nil } diff --git a/open.go b/open.go index f2c89ab..ae570e6 100644 --- a/open.go +++ b/open.go @@ -19,7 +19,7 @@ import ( // } // defer r.Close() // -func (path pathImpl) OpenReader() (io.ReadCloser, error) { +func (path PathImpl) OpenReader() (io.ReadCloser, error) { file, err := os.Open(path.Canonpath()) if err != nil { return nil, errors.Wrapf(err, "OpenReader on path %s fail (%+v)", path, path) @@ -43,16 +43,16 @@ func (path pathImpl) OpenReader() (io.ReadCloser, error) { // // writer.Write(some_bytes) // -func (path pathImpl) OpenWriter() (*os.File, error) { +func (path PathImpl) OpenWriter() (*os.File, error) { return path.openWriterFlag(os.O_RDWR | os.O_CREATE) } // OpenWriterAppend create new writer, similar as `OpenWriter` but append (like `>`) -func (path pathImpl) OpenWriterAppend() (*os.File, error) { +func (path PathImpl) OpenWriterAppend() (*os.File, error) { return path.openWriterFlag(os.O_APPEND | os.O_CREATE | os.O_WRONLY) } -func (path pathImpl) openWriterFlag(flag int) (*os.File, error) { +func (path PathImpl) openWriterFlag(flag int) (*os.File, error) { file, err := os.OpenFile(path.String(), flag, 0775) if err != nil { return nil, err @@ -63,7 +63,7 @@ func (path pathImpl) openWriterFlag(flag int) (*os.File, error) { // Slurp read all file // like ioutil.ReadFile -func (path pathImpl) Slurp() (string, error) { +func (path PathImpl) Slurp() (string, error) { bytes, err := path.SlurpBytes() if err != nil { return "", err @@ -72,12 +72,12 @@ func (path pathImpl) Slurp() (string, error) { return string(bytes[:]), nil } -func (path pathImpl) SlurpBytes() ([]byte, error) { +func (path PathImpl) SlurpBytes() ([]byte, error) { return ioutil.ReadFile(path.String()) } // Spew write string to file -func (path pathImpl) Spew(content string) error { +func (path PathImpl) Spew(content string) error { file, err := path.OpenWriter() if err != nil { return err @@ -97,7 +97,7 @@ func (path pathImpl) Spew(content string) error { } // SpewBytes write bytes to file -func (path pathImpl) SpewBytes(bytes []byte) error { +func (path PathImpl) SpewBytes(bytes []byte) error { file, err := path.OpenWriter() if err != nil { return err @@ -124,7 +124,7 @@ func (path pathImpl) SpewBytes(bytes []byte) error { // linesFuncError := path.LinesWalker(func(line string) { // lines = append(lines, line) // }) -func (path pathImpl) LinesWalker(linesFunc LinesFunc) error { +func (path PathImpl) LinesWalker(linesFunc LinesFunc) error { reader, err := path.OpenReader() if err != nil { return err @@ -141,7 +141,7 @@ func (path pathImpl) LinesWalker(linesFunc LinesFunc) error { } // Read all lines and return as array of lines -func (path pathImpl) Lines() ([]string, error) { +func (path PathImpl) Lines() ([]string, error) { lines := make([]string, 0) linesFuncError := path.LinesWalker(func(line string) { @@ -153,7 +153,7 @@ func (path pathImpl) Lines() ([]string, error) { // CopyFrom copy stream from reader to path // (file after copy close and sync) -func (path pathImpl) CopyFrom(reader io.Reader) (int64, error) { +func (path PathImpl) CopyFrom(reader io.Reader) (int64, error) { file, err := path.OpenWriter() if err != nil { return 0, err diff --git a/parent.go b/parent.go index 2d75683..bf811e2 100644 --- a/parent.go +++ b/parent.go @@ -5,7 +5,7 @@ package pathutil // // Returns a `Path` of corresponding to the parent directory of the // original directory or file -func (path pathImpl) Parent() Path { +func (path PathImpl) Parent() Path { // path.String() can't be empty parent, _ := New(path.String(), "..") return parent diff --git a/remove.go b/remove.go index 3013385..1a76939 100644 --- a/remove.go +++ b/remove.go @@ -7,13 +7,13 @@ import ( // Remove file // err := path.Remove() // like os.Remove -func (path pathImpl) Remove() error { - return os.Remove(path.Path) +func (path PathImpl) Remove() error { + return os.Remove(path.path) } // Remove tree of directory(ies) include files // err := path.RemoveTree // like os.RemoveAll -func (path pathImpl) RemoveTree() error { +func (path PathImpl) RemoveTree() error { return os.RemoveAll(path.Canonpath()) } diff --git a/rename.go b/rename.go index 33f7a30..a026921 100644 --- a/rename.go +++ b/rename.go @@ -5,7 +5,7 @@ import ( ) // Rename path to new path -func (old pathImpl) Rename(new string) (Path, error) { +func (old PathImpl) Rename(new string) (Path, error) { newPath, err := New(new) if err != nil { return nil, err diff --git a/stat.go b/stat.go index 3998a97..f15ce13 100644 --- a/stat.go +++ b/stat.go @@ -6,8 +6,8 @@ import ( ) // Stat return os.FileInfo -func (path pathImpl) Stat() (os.FileInfo, error) { - file, err := os.Open(path.Path) +func (path PathImpl) Stat() (os.FileInfo, error) { + file, err := os.Open(path.path) if err != nil { return nil, err @@ -24,7 +24,7 @@ func (path pathImpl) Stat() (os.FileInfo, error) { // File or dir exists -func (path pathImpl) Exists() bool { +func (path PathImpl) Exists() bool { if _, err := path.Stat(); os.IsNotExist(err) { return false } @@ -33,7 +33,7 @@ func (path pathImpl) Exists() bool { } // IsDir return true if path is dir -func (path pathImpl) IsDir() bool { +func (path PathImpl) IsDir() bool { stat, err := path.Stat() if err != nil { return false @@ -44,13 +44,13 @@ func (path pathImpl) IsDir() bool { // IsFile return true is path exists and not dir // (symlinks, devs, regular files) -func (path pathImpl) IsFile() bool { +func (path PathImpl) IsFile() bool { return path.Exists() && !path.IsDir() } // IsRegularFile return true if path is regular file // (wihtout devs, symlinks, ...) -func (path pathImpl) IsRegularFile() bool { +func (path PathImpl) IsRegularFile() bool { stat, err := path.Stat() if err != nil { return false diff --git a/struct.go b/struct.go index 75f3493..10c9b84 100644 --- a/struct.go +++ b/struct.go @@ -1,5 +1,6 @@ package pathutil -type pathImpl struct { - Path string +// type PathImpl implements Path interface +type PathImpl struct { + path string } diff --git a/visit.go b/visit.go index cdc0cd3..877086d 100644 --- a/visit.go +++ b/visit.go @@ -5,7 +5,7 @@ import ( "path/filepath" ) -func (path pathImpl) Visit(visitFunc VisitFunc, visitOpt VisitOpt) { +func (path PathImpl) Visit(visitFunc VisitFunc, visitOpt VisitOpt) { walkFn := func(file string, info os.FileInfo, err error) error { if info != nil && info.IsDir() && file != path.String() && !visitOpt.Recurse { return filepath.SkipDir From 09e35ee8ac55793f600a70e71fc9e0ef8ffa25c2 Mon Sep 17 00:00:00 2001 From: Jan Seidl Date: Fri, 9 Feb 2018 00:02:32 +0100 Subject: [PATCH 45/54] travis and appveyor use Makefile --- .travis.yml | 9 ++++----- appveyor.yml | 9 +++++++-- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index 79cf2ba..b0bb7de 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,19 +1,18 @@ language: go go: - - 1.2 -# - 1.3 - - 1.4 - 1.5 - 1.6 - 1.7 + - 1.8 + - 1.9 - tip install: - - go get -t -v -d ./... + - make setup script: - - ./test.sh + - make ci after_success: - bash <(curl -s https://codecov.io/bash) diff --git a/appveyor.yml b/appveyor.yml index ff554df..b548d4c 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -6,9 +6,14 @@ clone_folder: c:\go\src\github.com\JaSei\pathutil-go platform: x64 install: + - copy c:\MinGW\bin\mingw32-make.exe c:\MinGW\bin\make.exe + - set GOPATH=C:\Users\appveyor\go + - set PATH=%PATH%;c:\MinGW\bin + - set PATH=%PATH%;%GOPATH%\bin;c:\go\bin + - set GOBIN=%GOPATH%\bin - go version - go env - - go get -v -t + - make setup build_script: - - go test -v ./... + - make ci From 90bb7dfaa9defe0829b8149ae3389cb06b4a2e7b Mon Sep 17 00:00:00 2001 From: Jan Seidl Date: Fri, 9 Feb 2018 00:40:05 +0100 Subject: [PATCH 46/54] fix check of linter --- README.md | 14 ++++----- append_test.go | 4 +-- child_test.go | 4 +-- copy.go | 14 +++++++-- copy_test.go | 11 +++++-- crypto.go | 8 +++-- crypto_test.go | 8 +++-- examples/download_test.go | 8 +++-- examples/json_test.go | 5 +-- examples/recursive_sha256sum_test.go | 3 +- examples/wc_test.go | 7 +++-- new.go | 8 +++-- new_test.go | 23 +++++++++----- open.go | 46 +++++++++++++++------------- open_test.go | 8 +++-- stat_test.go | 3 +- visit.go | 4 +-- visit_test.go | 3 +- 18 files changed, 114 insertions(+), 67 deletions(-) diff --git a/README.md b/README.md index 4eb8097..280ada3 100644 --- a/README.md +++ b/README.md @@ -173,7 +173,7 @@ for cleanup use `defer` #### func NewTempFile ```go -func NewTempFile(options TempOpt) (Path, error) +func NewTempFile(options TempOpt) (p Path, err error) ``` #### type PathImpl @@ -234,20 +234,20 @@ func (path PathImpl) Children() ([]Path, error) #### func (PathImpl) CopyFile ```go -func (srcPath PathImpl) CopyFile(dst string) (Path, error) +func (srcPath PathImpl) CopyFile(dst string) (p Path, err error) ``` #### func (PathImpl) CopyFrom ```go -func (path PathImpl) CopyFrom(reader io.Reader) (int64, error) +func (path PathImpl) CopyFrom(reader io.Reader) (copyied int64, err error) ``` CopyFrom copy stream from reader to path (file after copy close and sync) #### func (PathImpl) Crypto ```go -func (path PathImpl) Crypto(hash crypto.Hash) (*CryptoHash, error) +func (path PathImpl) Crypto(hash crypto.Hash) (c *CryptoHash, err error) ``` #### func (PathImpl) Exists @@ -287,7 +287,7 @@ Read all lines and return as array of lines #### func (PathImpl) LinesWalker ```go -func (path PathImpl) LinesWalker(linesFunc LinesFunc) error +func (path PathImpl) LinesWalker(linesFunc LinesFunc) (err error) ``` LinesWalker read lines in file and call LinesFunc with line parameter @@ -416,14 +416,14 @@ func (path PathImpl) SlurpBytes() ([]byte, error) #### func (PathImpl) Spew ```go -func (path PathImpl) Spew(content string) error +func (path PathImpl) Spew(content string) (err error) ``` Spew write string to file #### func (PathImpl) SpewBytes ```go -func (path PathImpl) SpewBytes(bytes []byte) error +func (path PathImpl) SpewBytes(bytes []byte) (err error) ``` SpewBytes write bytes to file diff --git a/append_test.go b/append_test.go index 8ed93d9..d9aa7b5 100644 --- a/append_test.go +++ b/append_test.go @@ -10,13 +10,13 @@ func TestAppend(t *testing.T) { temp, err := NewTempFile(TempOpt{}) assert.NoError(t, err) - temp.Append("test\n") + assert.NoError(t, temp.Append("test\n")) content, err := temp.Slurp() assert.NoError(t, err) assert.Equal(t, "test\n", content) - temp.Append("test2") + assert.NoError(t, temp.Append("test2")) content, err = temp.Slurp() assert.NoError(t, err) diff --git a/child_test.go b/child_test.go index 61fd3d4..575c13e 100644 --- a/child_test.go +++ b/child_test.go @@ -30,9 +30,9 @@ func TestChildren(t *testing.T) { }() a, _ := tempdir.Child("a", "c") - a.MakePath() + assert.NoError(t, a.MakePath()) b, _ := tempdir.Child("b") - b.MakePath() + assert.NoError(t, b.MakePath()) children, err := tempdir.Children() assert.NoError(t, err) diff --git a/copy.go b/copy.go index ccfd1fc..71b03e1 100644 --- a/copy.go +++ b/copy.go @@ -5,7 +5,7 @@ import ( "os" ) -func (srcPath PathImpl) CopyFile(dst string) (Path, error) { +func (srcPath PathImpl) CopyFile(dst string) (p Path, err error) { dstPath, err := New(dst) if err != nil { return nil, err @@ -24,13 +24,21 @@ func (srcPath PathImpl) CopyFile(dst string) (Path, error) { if err != nil { return nil, err } - defer originalFile.Close() + defer func() { + if errClose := originalFile.Close(); errClose != nil { + err = errClose + } + }() newFile, err := os.Create(dst) if err != nil { return nil, err } - defer newFile.Close() + defer func() { + if errClose := newFile.Close(); errClose != nil { + err = errClose + } + }() _, err = io.Copy(newFile, originalFile) if err != nil { diff --git a/copy_test.go b/copy_test.go index 7e1468c..b2203b7 100644 --- a/copy_test.go +++ b/copy_test.go @@ -1,16 +1,19 @@ package pathutil import ( - "github.com/stretchr/testify/assert" "os" "testing" + + "github.com/stretchr/testify/assert" ) func TestCopyFileDstFileExists(t *testing.T) { src, _ := New("copy_test.go") dst, err := NewTempFile(TempOpt{}) assert.Nil(t, err) - defer dst.Remove() + defer func() { + assert.NoError(t, dst.Remove()) + }() assert.Exactly(t, true, dst.Exists(), "dst file exists before copy") newDst, err := src.CopyFile(dst.String()) @@ -32,7 +35,9 @@ func TestCopyFileDstIsDir(t *testing.T) { return } - defer newDst.Remove() + defer func() { + assert.NoError(t, newDst.Remove()) + }() assert.Exactly(t, true, newDst.Exists(), "dst after copy exists") assert.Exactly(t, true, newDst.IsFile(), "dst is file") diff --git a/crypto.go b/crypto.go index 53ca2df..9cdd086 100644 --- a/crypto.go +++ b/crypto.go @@ -14,12 +14,16 @@ import ( // hash, err := path.Crypto(crypto.SHA256) // fmt.Println(hash.HexSum()) -func (path PathImpl) Crypto(hash crypto.Hash) (*CryptoHash, error) { +func (path PathImpl) Crypto(hash crypto.Hash) (c *CryptoHash, err error) { reader, err := path.OpenReader() if err != nil { return nil, err } - defer reader.Close() + defer func() { + if errClose := reader.Close(); errClose != nil { + err = errClose + } + }() h := hash.New() diff --git a/crypto_test.go b/crypto_test.go index d439d1c..6240b1a 100644 --- a/crypto_test.go +++ b/crypto_test.go @@ -2,8 +2,9 @@ package pathutil import ( "crypto" - "github.com/stretchr/testify/assert" "testing" + + "github.com/stretchr/testify/assert" ) const emptyFileSha256Hex = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" @@ -13,9 +14,12 @@ var emptyFileSha256Bin = []uint8{0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, func TestPathCrypto(t *testing.T) { path, err := NewTempFile(TempOpt{}) assert.Nil(t, err) - defer path.Remove() + defer func() { + assert.NoError(t, path.Remove()) + }() hash, err := path.Crypto(crypto.Hash(crypto.SHA256)) + assert.NoError(t, err) assert.Equal(t, emptyFileSha256Hex, hash.HexSum()) assert.Equal(t, emptyFileSha256Bin, hash.BinSum()) diff --git a/examples/download_test.go b/examples/download_test.go index aeae415..2ad48e2 100644 --- a/examples/download_test.go +++ b/examples/download_test.go @@ -15,11 +15,15 @@ func TestDownload(t *testing.T) { t.Fatal("Connectivity problem") } - defer response.Body.Close() + defer func() { + assert.NoError(t, response.Body.Close()) + }() temp, err := pathutil.NewTempFile(pathutil.TempOpt{}) - defer temp.Remove() + defer func() { + assert.NoError(t, temp.Remove()) + }() assert.Nil(t, err) diff --git a/examples/json_test.go b/examples/json_test.go index 36ce7bd..233de0d 100644 --- a/examples/json_test.go +++ b/examples/json_test.go @@ -2,9 +2,10 @@ package pathutil_test import ( "encoding/json" + "testing" + "github.com/JaSei/pathutil-go" "github.com/stretchr/testify/assert" - "testing" ) type FileSource struct { @@ -54,7 +55,7 @@ func TestLoadJsonViaSlurp(t *testing.T) { assert.Nil(t, err) decodedJson := new(FileInfo) - json.Unmarshal(jsonBytes, decodedJson) + assert.NoError(t, json.Unmarshal(jsonBytes, decodedJson)) assert.Equal(t, &expected, decodedJson) diff --git a/examples/recursive_sha256sum_test.go b/examples/recursive_sha256sum_test.go index 0a6d50e..587829d 100644 --- a/examples/recursive_sha256sum_test.go +++ b/examples/recursive_sha256sum_test.go @@ -3,9 +3,10 @@ package pathutil_test import ( "crypto" "fmt" + "testing" + "github.com/JaSei/pathutil-go" "github.com/stretchr/testify/assert" - "testing" ) func TestVisitRecursiveAndHashAllFiles(t *testing.T) { diff --git a/examples/wc_test.go b/examples/wc_test.go index 37652d1..d394299 100644 --- a/examples/wc_test.go +++ b/examples/wc_test.go @@ -1,14 +1,15 @@ package pathutil_test import ( - "github.com/JaSei/pathutil-go" - "github.com/stretchr/testify/assert" "strings" "testing" + + "github.com/JaSei/pathutil-go" + "github.com/stretchr/testify/assert" ) func wc(path pathutil.Path) (lines, words, chars int) { - path.LinesWalker(func(line string) { + _ = path.LinesWalker(func(line string) { lines++ w := strings.Split(line, " ") diff --git a/new.go b/new.go index 74a090d..f9104b8 100644 --- a/new.go +++ b/new.go @@ -51,13 +51,17 @@ type TempOpt struct { // temp.Remove() // -func NewTempFile(options TempOpt) (Path, error) { +func NewTempFile(options TempOpt) (p Path, err error) { file, err := ioutil.TempFile(options.Dir, options.Prefix) if err != nil { return nil, errors.Wrapf(err, "NewTempFile(%+v) fail", options) } - defer file.Close() + defer func() { + if errClose := file.Close(); errClose != nil { + err = errClose + } + }() return New(file.Name()) } diff --git a/new_test.go b/new_test.go index e76bf12..12f95f1 100644 --- a/new_test.go +++ b/new_test.go @@ -1,8 +1,9 @@ package pathutil import ( - "github.com/stretchr/testify/assert" "testing" + + "github.com/stretchr/testify/assert" ) func TestNew(t *testing.T) { @@ -19,20 +20,26 @@ func TestNew(t *testing.T) { } func TestNewTempFile(t *testing.T) { - temp, err := NewTempFile(TempOpt{}) - defer temp.Remove() - assert.NotNil(t, temp) + temp1, err := NewTempFile(TempOpt{}) + defer func() { + assert.NoError(t, temp1.Remove()) + }() + assert.NotNil(t, temp1) assert.Nil(t, err) - temp, err = NewTempFile(TempOpt{Dir: "."}) - defer temp.Remove() - assert.NotNil(t, temp) + temp2, err := NewTempFile(TempOpt{Dir: "."}) + defer func() { + assert.NoError(t, temp2.Remove()) + }() + assert.NotNil(t, temp2) assert.Nil(t, err) } func TestTempFile(t *testing.T) { temp, err := NewTempFile(TempOpt{Prefix: "bla"}) - defer temp.Remove() + defer func() { + assert.NoError(t, temp.Remove()) + }() assert.NotNil(t, temp) assert.Nil(t, err) diff --git a/open.go b/open.go index ae570e6..513d7e3 100644 --- a/open.go +++ b/open.go @@ -77,43 +77,37 @@ func (path PathImpl) SlurpBytes() ([]byte, error) { } // Spew write string to file -func (path PathImpl) Spew(content string) error { +func (path PathImpl) Spew(content string) (err error) { file, err := path.OpenWriter() if err != nil { return err } defer func() { - if err := file.Close(); err != nil { - panic(err) + if errClose := file.Close(); errClose != nil { + err = errClose } }() - if _, err := file.WriteString(content); err != nil { - return err - } - - return nil + _, err = file.WriteString(content) + return err } // SpewBytes write bytes to file -func (path PathImpl) SpewBytes(bytes []byte) error { +func (path PathImpl) SpewBytes(bytes []byte) (err error) { file, err := path.OpenWriter() if err != nil { return err } defer func() { - if err := file.Close(); err != nil { - panic(err) + if errClose := file.Close(); errClose != nil { + err = errClose } }() - if _, err := file.Write(bytes); err != nil { - return err - } - - return nil + _, err = file.Write(bytes) + return err } // LinesWalker read lines in file and call LinesFunc with line parameter @@ -124,12 +118,16 @@ func (path PathImpl) SpewBytes(bytes []byte) error { // linesFuncError := path.LinesWalker(func(line string) { // lines = append(lines, line) // }) -func (path PathImpl) LinesWalker(linesFunc LinesFunc) error { +func (path PathImpl) LinesWalker(linesFunc LinesFunc) (err error) { reader, err := path.OpenReader() if err != nil { return err } - defer reader.Close() + defer func() { + if errClose := reader.Close(); errClose != nil { + err = errClose + } + }() scanner := bufio.NewScanner(reader) @@ -153,18 +151,22 @@ func (path PathImpl) Lines() ([]string, error) { // CopyFrom copy stream from reader to path // (file after copy close and sync) -func (path PathImpl) CopyFrom(reader io.Reader) (int64, error) { +func (path PathImpl) CopyFrom(reader io.Reader) (copyied int64, err error) { file, err := path.OpenWriter() if err != nil { return 0, err } defer func() { - file.Close() - file.Sync() + if errSync := file.Sync(); errSync != nil { + err = errSync + } else if errClose := file.Close(); errClose != nil { + err = errClose + } + }() - copyied, err := io.Copy(file, reader) + copyied, err = io.Copy(file, reader) return copyied, err } diff --git a/open_test.go b/open_test.go index 6be3151..80c81e8 100644 --- a/open_test.go +++ b/open_test.go @@ -1,8 +1,9 @@ package pathutil import ( - "github.com/stretchr/testify/assert" "testing" + + "github.com/stretchr/testify/assert" ) func TestOpenReader(t *testing.T) { @@ -12,7 +13,9 @@ func TestOpenReader(t *testing.T) { reader, err := path.OpenReader() assert.Nil(t, err) - defer reader.Close() + defer func() { + assert.NoError(t, reader.Close()) + }() } func TestSlurp(t *testing.T) { @@ -21,6 +24,7 @@ func TestSlurp(t *testing.T) { assert.Nil(t, err) ctx, err := path.SlurpBytes() + assert.NoError(t, err) assert.Equal(t, 1066, len(ctx), "read LICENSE file") } diff --git a/stat_test.go b/stat_test.go index 4bedea7..d9e92d8 100644 --- a/stat_test.go +++ b/stat_test.go @@ -1,10 +1,11 @@ package pathutil import ( - "github.com/stretchr/testify/assert" "os" "runtime" "testing" + + "github.com/stretchr/testify/assert" ) func TestExists(t *testing.T) { diff --git a/visit.go b/visit.go index 877086d..eef3083 100644 --- a/visit.go +++ b/visit.go @@ -20,12 +20,12 @@ func (path PathImpl) Visit(visitFunc VisitFunc, visitOpt VisitOpt) { return nil } - path, err := New(file) + path, _ := New(file) visitFunc(path) return nil } - filepath.Walk(path.String(), walkFn) + _ = filepath.Walk(path.String(), walkFn) } diff --git a/visit_test.go b/visit_test.go index ef0c1f2..a185793 100644 --- a/visit_test.go +++ b/visit_test.go @@ -1,8 +1,9 @@ package pathutil import ( - "github.com/stretchr/testify/assert" "testing" + + "github.com/stretchr/testify/assert" ) func TestVisitFlat(t *testing.T) { From f185f4f1e47181ef1e7faf8591850ae9182be78a Mon Sep 17 00:00:00 2001 From: Jan Seidl Date: Fri, 9 Feb 2018 20:15:14 +0100 Subject: [PATCH 47/54] disable linters for lower version then go 1.8 --- Makefile | 14 ++++++++++++-- copy.go | 2 +- examples/json_test.go | 4 ++-- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 6de90d5..0ad7def 100644 --- a/Makefile +++ b/Makefile @@ -1,12 +1,17 @@ HELP?=$$(go run main.go --help 2>&1) VERSION?=$$(cat VERSION) +GO18?=$(shell go version | grep -E "go1\.[89]") setup: ## Install all the build and lint dependencies - go get -u github.com/alecthomas/gometalinter go get -u github.com/golang/dep/cmd/dep go get -u golang.org/x/tools/cmd/cover dep ensure +ifeq ($(GO18),) + @echo no install metalinter, because metalinter need go1.8+ +else + go get -u github.com/alecthomas/gometalinter gometalinter --install +endif go get -u github.com/robertkrimen/godocdown/godocdown generate: ## Generate README.md @@ -22,7 +27,9 @@ fmt: ## gofmt and goimports all go files find . -name '*.go' -not -wholename './vendor/*' | while read -r file; do gofmt -w -s "$$file"; goimports -w "$$file"; done lint: ## Run all the linters - +ifeq ($(GO18),) + @echo no run metalinter, because metalinter need go1.8+ +else #https://github.com/golang/go/issues/19490 #--enable=vetshadow \ @@ -38,8 +45,11 @@ lint: ## Run all the linters --enable=errcheck \ --enable=vet \ --deadline=10m \ + --enable=vetshadow \ ./... +endif + ci: test lint ## Run all the tests and code checks build: ## Build the app diff --git a/copy.go b/copy.go index 71b03e1..06c06c4 100644 --- a/copy.go +++ b/copy.go @@ -12,7 +12,7 @@ func (srcPath PathImpl) CopyFile(dst string) (p Path, err error) { } if dstPath.IsDir() { - dstPath, err := New(dst, srcPath.Basename()) + dstPath, err = New(dst, srcPath.Basename()) if err != nil { return nil, err } else { diff --git a/examples/json_test.go b/examples/json_test.go index 233de0d..8e800ba 100644 --- a/examples/json_test.go +++ b/examples/json_test.go @@ -21,8 +21,8 @@ type FileInfo struct { var expected = FileInfo{ FileId: "01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b", Sources: []FileSource{ - FileSource{Path: "c:\\tmp\\empty_file", Size: 0}, - FileSource{Path: "/tmp/empty_file", Size: 0}, + {Path: "c:\\tmp\\empty_file", Size: 0}, + {Path: "/tmp/empty_file", Size: 0}, }, } From d396477000c149195b6da27061cb3d421e477e6b Mon Sep 17 00:00:00 2001 From: Jan Seidl Date: Fri, 9 Feb 2018 20:18:39 +0100 Subject: [PATCH 48/54] fix appveyor test --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index b548d4c..08e40d0 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,6 +1,6 @@ version: "{build}" -clone_folder: c:\go\src\github.com\JaSei\pathutil-go +clone_folder: C:\Users\appveyor\go\src\github.com\JaSei\pathutil-go #os: Windows Server 2012 R2 platform: x64 From 989193d73a8646472659e6593018d978916f0ef0 Mon Sep 17 00:00:00 2001 From: Jan Seidl Date: Fri, 9 Feb 2018 20:21:41 +0100 Subject: [PATCH 49/54] fix test on windows --- parent_test.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/parent_test.go b/parent_test.go index bf69bd2..fe23f96 100644 --- a/parent_test.go +++ b/parent_test.go @@ -1,6 +1,7 @@ package pathutil import ( + "os" "testing" "github.com/stretchr/testify/assert" @@ -10,7 +11,7 @@ func TestParent(t *testing.T) { temp, err := NewTempDir(TempOpt{}) assert.NoError(t, err) - assert.Equal(t, "/tmp", temp.Parent().String()) + assert.Equal(t, os.TempDir(), temp.Parent().String()) root, err := New("/") assert.NoError(t, err) From b047fbe6747441ee7a6e5e799b6d7da1fde063e6 Mon Sep 17 00:00:00 2001 From: Jan Seidl Date: Fri, 9 Feb 2018 20:29:58 +0100 Subject: [PATCH 50/54] dep are download from github, no compiled (support lower versins of go) --- .travis.yml | 4 ++++ Makefile | 16 ++++++++++++++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index b0bb7de..632b8a2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,9 @@ language: go +os: + - linux + - osx + go: - 1.5 - 1.6 diff --git a/Makefile b/Makefile index 0ad7def..8128a79 100644 --- a/Makefile +++ b/Makefile @@ -1,10 +1,23 @@ HELP?=$$(go run main.go --help 2>&1) VERSION?=$$(cat VERSION) GO18?=$(shell go version | grep -E "go1\.[89]") +DEP?=$$(which dep) + +ifeq ($(OS),Windows_NT) + DEP_VERS=dep-windows-amd64 +else ifeq ($(OS), Darwin) + DEP_VERS=dep-darwin-amd64 +else + DEP_VERS=dep-linux-amd64 +endif setup: ## Install all the build and lint dependencies - go get -u github.com/golang/dep/cmd/dep go get -u golang.org/x/tools/cmd/cover + go get -u github.com/robertkrimen/godocdown/godocdown + @if [ "$(DEP)" = "" ]; then\ + curl -L https://github.com/golang/dep/releases/download/v0.4.1/$(DEP_VERS) >| $$GOPATH/bin/dep;\ + chmod +x $$GOPATH/bin/dep;\ + fi dep ensure ifeq ($(GO18),) @echo no install metalinter, because metalinter need go1.8+ @@ -12,7 +25,6 @@ else go get -u github.com/alecthomas/gometalinter gometalinter --install endif - go get -u github.com/robertkrimen/godocdown/godocdown generate: ## Generate README.md godocdown >| README.md From ed1c94969758f2a5017e66b4ef7d057fe0161a22 Mon Sep 17 00:00:00 2001 From: Jan Seidl Date: Fri, 9 Feb 2018 20:33:51 +0100 Subject: [PATCH 51/54] fix windows test --- parent_test.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/parent_test.go b/parent_test.go index fe23f96..8cf9675 100644 --- a/parent_test.go +++ b/parent_test.go @@ -11,7 +11,10 @@ func TestParent(t *testing.T) { temp, err := NewTempDir(TempOpt{}) assert.NoError(t, err) - assert.Equal(t, os.TempDir(), temp.Parent().String()) + tempDir, err := New(os.TempDir()) + assert.NoError(t, err) + + assert.Equal(t, tempDir.String(), temp.Parent().String()) root, err := New("/") assert.NoError(t, err) From 1c7bb2144642aeb75f8ab8eb7c7419beaaf1bcdc Mon Sep 17 00:00:00 2001 From: Jan Seidl Date: Fri, 9 Feb 2018 20:52:29 +0100 Subject: [PATCH 52/54] fix dep for windows --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 8128a79..8b7fa77 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ GO18?=$(shell go version | grep -E "go1\.[89]") DEP?=$$(which dep) ifeq ($(OS),Windows_NT) - DEP_VERS=dep-windows-amd64 + DEP_VERS=dep-windows-amd64.exe else ifeq ($(OS), Darwin) DEP_VERS=dep-darwin-amd64 else From 65fb5078e172ff66504ea9fb9c751e5175f69dcd Mon Sep 17 00:00:00 2001 From: Jan Seidl Date: Fri, 9 Feb 2018 21:00:40 +0100 Subject: [PATCH 53/54] support for go 1.5 and remove macos support (don't work) --- .travis.yml | 1 - Makefile | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 632b8a2..858a91c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,7 +2,6 @@ language: go os: - linux - - osx go: - 1.5 diff --git a/Makefile b/Makefile index 8b7fa77..a0476a7 100644 --- a/Makefile +++ b/Makefile @@ -2,6 +2,7 @@ HELP?=$$(go run main.go --help 2>&1) VERSION?=$$(cat VERSION) GO18?=$(shell go version | grep -E "go1\.[89]") DEP?=$$(which dep) +export GO15VENDOREXPERIMENT=1 ifeq ($(OS),Windows_NT) DEP_VERS=dep-windows-amd64.exe From 709989398e55a651b8b7e07304a9b9288a9287e9 Mon Sep 17 00:00:00 2001 From: Jan Seidl Date: Fri, 9 Feb 2018 21:04:48 +0100 Subject: [PATCH 54/54] remove tip, because is really slow --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 858a91c..bfd1c4c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,7 +9,6 @@ go: - 1.7 - 1.8 - 1.9 - - tip install: - make setup