From b42e0b7d71b651fc50c4f1833cdb8e61008b008e Mon Sep 17 00:00:00 2001 From: Mark Bates Date: Sat, 31 Aug 2019 17:00:24 -0400 Subject: [PATCH 01/46] job jargon --- .gitignore | 1 + Makefile | 6 +- create_test.go | 4 +- fs/file.go | 22 +++++ fs/fs.go | 20 ++++ fs/fstest/file.go | 37 +++++++ fs/hdfs/file.go | 82 +++++++++++++++ fs/hdfs/hdfs.go | 153 ++++++++++++++++++++++++++++ fs/info.go | 104 +++++++++++++++++++ fs/memfs/create.go | 40 ++++++++ fs/memfs/create_test.go | 90 +++++++++++++++++ fs/memfs/file.go | 203 ++++++++++++++++++++++++++++++++++++++ fs/memfs/file_test.go | 70 +++++++++++++ fs/memfs/http.go | 1 + fs/memfs/http_test.go | 84 ++++++++++++++++ fs/memfs/json.go | 66 +++++++++++++ fs/memfs/json_test.go | 43 ++++++++ fs/memfs/memfs.go | 58 +++++++++++ fs/memfs/memfs_test.go | 26 +++++ fs/memfs/mkdirall.go | 61 ++++++++++++ fs/memfs/mkdirall_test.go | 25 +++++ fs/memfs/open.go | 32 ++++++ fs/memfs/open_test.go | 34 +++++++ fs/memfs/stat.go | 18 ++++ fs/memfs/stat_test.go | 25 +++++ fs/memfs/walk.go | 38 +++++++ fs/memfs/walk_test.go | 69 +++++++++++++ fs/path.go | 39 ++++++++ internal/maps/files.go | 146 +++++++++++++++++++++++++++ internal/maps/infos.go | 126 +++++++++++++++++++++++ internal/maps/paths.go | 182 ++++++++++++++++++++++++++++++++++ 31 files changed, 1902 insertions(+), 3 deletions(-) create mode 100644 fs/file.go create mode 100644 fs/fs.go create mode 100644 fs/fstest/file.go create mode 100644 fs/hdfs/file.go create mode 100644 fs/hdfs/hdfs.go create mode 100644 fs/info.go create mode 100644 fs/memfs/create.go create mode 100644 fs/memfs/create_test.go create mode 100644 fs/memfs/file.go create mode 100644 fs/memfs/file_test.go create mode 100644 fs/memfs/http.go create mode 100644 fs/memfs/http_test.go create mode 100644 fs/memfs/json.go create mode 100644 fs/memfs/json_test.go create mode 100644 fs/memfs/memfs.go create mode 100644 fs/memfs/memfs_test.go create mode 100644 fs/memfs/mkdirall.go create mode 100644 fs/memfs/mkdirall_test.go create mode 100644 fs/memfs/open.go create mode 100644 fs/memfs/open_test.go create mode 100644 fs/memfs/stat.go create mode 100644 fs/memfs/stat_test.go create mode 100644 fs/memfs/walk.go create mode 100644 fs/memfs/walk_test.go create mode 100644 fs/path.go create mode 100644 internal/maps/files.go create mode 100644 internal/maps/infos.go create mode 100644 internal/maps/paths.go diff --git a/.gitignore b/.gitignore index a10e98a..9115a58 100644 --- a/.gitignore +++ b/.gitignore @@ -28,3 +28,4 @@ bin/* gin-bin .idea/ pkged.go +cover.out diff --git a/Makefile b/Makefile index 7f64c7a..94018ac 100644 --- a/Makefile +++ b/Makefile @@ -16,6 +16,11 @@ test: tidy $(GO_BIN) test -cover -tags ${TAGS} -timeout 5s ./... make tidy +cov: + $(GO_BIN) test -coverprofile cover.out -tags ${TAGS} ./... + go tool cover -html cover.out + make tidy + ci-test: $(GO_BIN) test -tags ${TAGS} -race ./... @@ -43,4 +48,3 @@ release: make tidy - diff --git a/create_test.go b/create_test.go index 79caf2a..f53b023 100644 --- a/create_test.go +++ b/create_test.go @@ -9,7 +9,7 @@ import ( "github.com/stretchr/testify/require" ) -func Testg_Create(t *testing.T) { +func Test_Create(t *testing.T) { r := require.New(t) f, err := Create("/hello.txt") @@ -28,7 +28,7 @@ func Testg_Create(t *testing.T) { r.Equal("github.com/markbates/pkger", her.ImportPath) } -func Testg_Create_Write(t *testing.T) { +func Test_Create_Write(t *testing.T) { r := require.New(t) f, err := Create("/hello.txt") diff --git a/fs/file.go b/fs/file.go new file mode 100644 index 0000000..d558b7b --- /dev/null +++ b/fs/file.go @@ -0,0 +1,22 @@ +package fs + +import ( + "net/http" + "os" + + "github.com/markbates/pkger/here" +) + +type File interface { + Close() error + FilePath() string + Info() here.Info + Name() string + Open(name string) (http.File, error) + Path() Path + Read(p []byte) (int, error) + Readdir(count int) ([]os.FileInfo, error) + Seek(offset int64, whence int) (int64, error) + Stat() (os.FileInfo, error) + Write(b []byte) (int, error) +} diff --git a/fs/fs.go b/fs/fs.go new file mode 100644 index 0000000..99482a3 --- /dev/null +++ b/fs/fs.go @@ -0,0 +1,20 @@ +package fs + +import ( + "os" + "path/filepath" + + "github.com/markbates/pkger/here" +) + +type FileSystem interface { + Create(name string) (File, error) + Current() (here.Info, error) + Info(p string) (here.Info, error) + MkdirAll(p string, perm os.FileMode) error + Open(name string) (File, error) + Parse(p string) (Path, error) + ReadFile(s string) ([]byte, error) + Stat(name string) (os.FileInfo, error) + Walk(p string, wf filepath.WalkFunc) error +} diff --git a/fs/fstest/file.go b/fs/fstest/file.go new file mode 100644 index 0000000..cc675df --- /dev/null +++ b/fs/fstest/file.go @@ -0,0 +1,37 @@ +package fstest + +import ( + "bytes" + "io" + + "github.com/markbates/pkger/fs" +) + +type TestFile struct { + Name string + Data []byte +} + +func (t TestFile) Create(fx fs.FileSystem) error { + f, err := fx.Create(t.Name) + if err != nil { + return err + } + _, err = io.Copy(f, bytes.NewReader(t.Data)) + if err != nil { + return err + } + return f.Close() +} + +type TestFiles map[string]TestFile + +func (t TestFiles) Create(fx fs.FileSystem) error { + for k, f := range t { + f.Name = k + if err := f.Create(fx); err != nil { + return err + } + } + return nil +} diff --git a/fs/hdfs/file.go b/fs/hdfs/file.go new file mode 100644 index 0000000..572e4cd --- /dev/null +++ b/fs/hdfs/file.go @@ -0,0 +1,82 @@ +package hdfs + +import ( + "net/http" + "os" + + "github.com/markbates/pkger/fs" + "github.com/markbates/pkger/here" +) + +var _ fs.File = &File{} + +type File struct { + *os.File + filePath string + info *fs.FileInfo + her here.Info + path fs.Path + fs fs.FileSystem +} + +func NewFile(fx fs.FileSystem, osf *os.File) (*File, error) { + info, err := osf.Stat() + if err != nil { + return nil, err + } + + pt, err := fx.Parse(info.Name()) + if err != nil { + return nil, err + } + + f := &File{ + File: osf, + filePath: info.Name(), + path: pt, + fs: fx, + } + f.info = fs.WithName(pt.Name, info) + + her, err := here.Package(pt.Pkg) + if err != nil { + return nil, err + } + f.her = her + return f, nil +} + +func (f *File) Close() error { + return f.File.Close() +} + +func (f *File) FilePath() string { + return f.filePath +} + +func (f *File) Info() here.Info { + return f.her +} + +func (f *File) Name() string { + return f.info.Name() +} + +func (f *File) Open(name string) (http.File, error) { + return f.File, nil +} + +func (f *File) Path() fs.Path { + return f.path +} + +func (f *File) Stat() (os.FileInfo, error) { + if f.info == nil { + info, err := os.Stat(f.filePath) + if err != nil { + return nil, err + } + f.info = fs.NewFileInfo(info) + } + return f.info, nil +} diff --git a/fs/hdfs/hdfs.go b/fs/hdfs/hdfs.go new file mode 100644 index 0000000..9d05773 --- /dev/null +++ b/fs/hdfs/hdfs.go @@ -0,0 +1,153 @@ +package hdfs + +import ( + "fmt" + "io/ioutil" + "os" + "path/filepath" + "strings" + + "github.com/markbates/pkger/fs" + "github.com/markbates/pkger/here" + "github.com/markbates/pkger/internal/maps" +) + +var _ fs.FileSystem = &FS{} + +type FS struct { + infos *maps.Infos + paths *maps.Paths + current here.Info +} + +func New() (*FS, error) { + f := &FS{ + infos: &maps.Infos{}, + paths: &maps.Paths{}, + } + + var err error + f.current, err = here.Current() + return f, err +} + +func (fx *FS) Create(name string) (fs.File, error) { + name, err := fx.locate(name) + if err != nil { + return nil, err + } + f, err := os.Create(name) + if err != nil { + return nil, err + } + return NewFile(fx, f) +} + +func (f *FS) Current() (here.Info, error) { + return f.current, nil +} + +func (f *FS) Info(p string) (here.Info, error) { + info, ok := f.infos.Load(p) + if ok { + return info, nil + } + + info, err := here.Package(p) + if err != nil { + return info, err + } + f.infos.Store(p, info) + return info, nil +} + +func (f *FS) MkdirAll(p string, perm os.FileMode) error { + p, err := f.locate(p) + if err != nil { + return err + } + return os.MkdirAll(p, perm) +} + +func (fx *FS) Open(name string) (fs.File, error) { + name, err := fx.locate(name) + if err != nil { + return nil, err + } + f, err := os.Open(name) + if err != nil { + return nil, err + } + return NewFile(fx, f) +} + +func (f *FS) Parse(p string) (fs.Path, error) { + return f.paths.Parse(p) +} + +func (f *FS) ReadFile(s string) ([]byte, error) { + s, err := f.locate(s) + if err != nil { + return nil, err + } + return ioutil.ReadFile(s) +} + +func (f *FS) Stat(name string) (os.FileInfo, error) { + name, err := f.locate(name) + if err != nil { + return nil, err + } + return os.Stat(name) +} + +func (f *FS) Walk(p string, wf filepath.WalkFunc) error { + fp, err := f.locate(p) + if err != nil { + return err + } + + pt, err := f.Parse(p) + if err != nil { + return err + } + err = filepath.Walk(fp, func(path string, fi os.FileInfo, err error) error { + if err != nil { + return err + } + + path = strings.TrimPrefix(path, fp) + pt, err := f.Parse(fmt.Sprintf("%s:%s", pt.Pkg, path)) + if err != nil { + return err + } + return wf(pt.String(), fs.WithName(path, fs.NewFileInfo(fi)), nil) + }) + + return err +} + +func (f *FS) locate(p string) (string, error) { + pt, err := f.Parse(p) + if err != nil { + return "", err + } + + var info here.Info + if pt.Pkg == "." { + info, err = f.Current() + if err != nil { + return "", err + } + pt.Pkg = info.ImportPath + } + + if info.IsZero() { + info, err = f.Info(pt.Pkg) + if err != nil { + return "", fmt.Errorf("%s: %s", pt, err) + } + } + fp := filepath.Join(info.Dir, pt.Name) + return fp, nil +} diff --git a/fs/info.go b/fs/info.go new file mode 100644 index 0000000..75721db --- /dev/null +++ b/fs/info.go @@ -0,0 +1,104 @@ +package fs + +import ( + "encoding/json" + "os" + "strings" + "time" +) + +const timeFmt = time.RFC3339Nano + +type ModTime time.Time + +func (m ModTime) MarshalJSON() ([]byte, error) { + t := time.Time(m) + return json.Marshal(t.Format(timeFmt)) +} + +func (m *ModTime) UnmarshalJSON(b []byte) error { + t := time.Time{} + if err := json.Unmarshal(b, &t); err != nil { + return err + } + (*m) = ModTime(t) + return nil +} + +type Details struct { + Name string `json:"name"` + Size int64 `json:"size"` + Mode os.FileMode `json:"mode"` + ModTime ModTime `json:"mod_time"` + IsDir bool `json:"is_dir"` + Sys interface{} `json:"sys"` +} +type FileInfo struct { + Details `json:"details"` +} + +func (f *FileInfo) String() string { + b, _ := json.MarshalIndent(f, "", " ") + return string(b) +} + +func (f *FileInfo) Name() string { + return f.Details.Name +} + +func (f *FileInfo) Size() int64 { + return f.Details.Size +} + +func (f *FileInfo) Mode() os.FileMode { + return f.Details.Mode +} + +func (f *FileInfo) ModTime() time.Time { + return time.Time(f.Details.ModTime) +} + +func (f *FileInfo) IsDir() bool { + return f.Details.IsDir +} + +func (f *FileInfo) Sys() interface{} { + return f.Details.Sys +} + +var _ os.FileInfo = &FileInfo{} + +func NewFileInfo(info os.FileInfo) *FileInfo { + fi := &FileInfo{ + Details: Details{ + Name: cleanName(info.Name()), + Size: info.Size(), + Mode: info.Mode(), + ModTime: ModTime(info.ModTime()), + IsDir: info.IsDir(), + Sys: info.Sys(), + }, + } + return fi +} + +func WithName(name string, info os.FileInfo) *FileInfo { + if ft, ok := info.(*FileInfo); ok { + ft.Details.Name = cleanName(name) + return ft + } + + fo := NewFileInfo(info) + fo.Details.Name = cleanName(name) + return fo +} + +func cleanName(s string) string { + if strings.Contains(s, "\\") { + s = strings.Replace(s, "\\", "/", -1) + } + if !strings.HasPrefix(s, "/") { + s = "/" + s + } + return s +} diff --git a/fs/memfs/create.go b/fs/memfs/create.go new file mode 100644 index 0000000..76bd253 --- /dev/null +++ b/fs/memfs/create.go @@ -0,0 +1,40 @@ +package memfs + +import ( + "path/filepath" + "time" + + "github.com/markbates/pkger/fs" +) + +func (fx *FS) Create(name string) (fs.File, error) { + pt, err := fx.Parse(name) + if err != nil { + return nil, err + } + + her, err := fx.Info(pt.Pkg) + if err != nil { + return nil, err + } + f := &File{ + path: pt, + her: her, + info: &fs.FileInfo{ + Details: fs.Details{ + Name: pt.Name, + Mode: 0666, + ModTime: fs.ModTime(time.Now()), + }, + }, + fs: fx, + } + + fx.files.Store(pt, f) + + dir := filepath.Dir(pt.Name) + if err := fx.MkdirAll(dir, 0644); err != nil { + return nil, err + } + return f, nil +} diff --git a/fs/memfs/create_test.go b/fs/memfs/create_test.go new file mode 100644 index 0000000..411dbca --- /dev/null +++ b/fs/memfs/create_test.go @@ -0,0 +1,90 @@ +package memfs + +import ( + "io" + "os" + "strings" + "testing" + + "github.com/markbates/pkger/here" + "github.com/stretchr/testify/require" +) + +func Test_Create(t *testing.T) { + r := require.New(t) + + fs, err := New(here.Info{}) + f, err := fs.Create("/hello.txt") + r.NoError(err) + r.NotNil(f) + + fi, err := f.Stat() + r.NoError(err) + + r.Equal("/hello.txt", fi.Name()) + r.Equal(os.FileMode(0666), fi.Mode()) + r.NotZero(fi.ModTime()) +} + +func Test_Create_Write(t *testing.T) { + r := require.New(t) + + fs, err := New(here.Info{}) + f, err := fs.Create("/hello.txt") + r.NoError(err) + r.NotNil(f) + + fi, err := f.Stat() + r.NoError(err) + r.Zero(fi.Size()) + + r.Equal("/hello.txt", fi.Name()) + + mt := fi.ModTime() + r.NotZero(mt) + + sz, err := io.Copy(f, strings.NewReader(radio)) + r.NoError(err) + r.Equal(int64(1381), sz) + + r.NoError(f.Close()) + r.Equal(int64(1381), fi.Size()) + r.NotZero(fi.ModTime()) + r.NotEqual(mt, fi.ModTime()) +} + +const radio = `I was tuning in the shine on the late night dial +Doing anything my radio advised +With every one of those late night stations +Playing songs bringing tears to my eyes +I was seriously thinking about hiding the receiver +When the switch broke 'cause it's old +They're saying things that I can hardly believe +They really think we're getting out of control +Radio is a sound salvation +Radio is cleaning up the nation +They say you better listen to the voice of reason +But they don't give you any choice 'cause they think that it's treason +So you had better do as you are told +You better listen to the radio +I wanna bite the hand that feeds me +I wanna bite that hand so badly +I want to make them wish they'd never seen me +Some of my friends sit around every evening +And they worry about the times ahead +But everybody else is overwhelmed by indifference +And the promise of an early bed +You either shut up or get cut up; they don't wanna hear about it +It's only inches on the reel-to-reel +And the radio is in the hands of such a lot of fools +Tryin' to anesthetize the way that you feel +Radio is a sound salvation +Radio is cleaning up the nation +They say you better listen to the voice of reason +But they don't give you any choice 'cause they think that it's treason +So you had better do as you are told +You better listen to the radio +Wonderful radio +Marvelous radio +Wonderful radio +Radio, radio` diff --git a/fs/memfs/file.go b/fs/memfs/file.go new file mode 100644 index 0000000..612c12b --- /dev/null +++ b/fs/memfs/file.go @@ -0,0 +1,203 @@ +package memfs + +import ( + "bytes" + "encoding/json" + "fmt" + "io" + "net/http" + "os" + "path" + "strings" + "time" + + "github.com/markbates/pkger/fs" + "github.com/markbates/pkger/here" +) + +const timeFmt = time.RFC3339Nano + +var _ fs.File = &File{} + +type File struct { + info *fs.FileInfo + her here.Info + path fs.Path + data []byte + parent fs.Path + writer *bytes.Buffer + reader io.Reader + fs fs.FileSystem +} + +func (f *File) Seek(offset int64, whence int) (int64, error) { + if sk, ok := f.reader.(io.Seeker); ok { + return sk.Seek(offset, whence) + } + return 0, nil +} + +func (f *File) Close() error { + defer func() { + f.reader = nil + f.writer = nil + }() + if f.reader != nil { + if c, ok := f.reader.(io.Closer); ok { + if err := c.Close(); err != nil { + return err + } + } + } + + if f.writer == nil { + return nil + } + + f.data = f.writer.Bytes() + + fi := f.info + fi.Details.Size = int64(len(f.data)) + fi.Details.ModTime = fs.ModTime(time.Now()) + f.info = fi + return nil +} + +func (f *File) Read(p []byte) (int, error) { + if len(f.data) > 0 && f.reader == nil { + f.reader = bytes.NewReader(f.data) + } + + if f.reader != nil { + return f.reader.Read(p) + } + + return 0, fmt.Errorf("unable to read %s", f.Name()) +} + +func (f *File) Write(b []byte) (int, error) { + if f.writer == nil { + f.writer = &bytes.Buffer{} + } + i, err := f.writer.Write(b) + return i, err +} + +func (f File) Info() here.Info { + return f.her +} + +func (f File) Stat() (os.FileInfo, error) { + if f.info == nil { + return nil, os.ErrNotExist + } + return f.info, nil +} + +func (f File) Name() string { + return f.info.Name() +} + +func (f File) FilePath() string { + return f.her.FilePath(f.Name()) +} + +func (f File) Path() fs.Path { + return f.path +} + +func (f File) String() string { + return f.Path().String() +} + +func (f File) Format(st fmt.State, verb rune) { + switch verb { + case 'v': + if st.Flag('+') { + b, err := json.MarshalIndent(f, "", " ") + if err != nil { + fmt.Fprint(os.Stderr, err) + return + } + fmt.Fprint(st, string(b)) + return + } + fmt.Fprint(st, f.String()) + case 'q': + fmt.Fprintf(st, "%q", f.String()) + default: + fmt.Fprint(st, f.String()) + } +} + +func (f *File) Readdir(count int) ([]os.FileInfo, error) { + var infos []os.FileInfo + root := f.Path().String() + err := f.fs.Walk(root, func(path string, info os.FileInfo, err error) error { + if err != nil { + return err + } + + if count > 0 && len(infos) == count { + return io.EOF + } + + pt, err := f.fs.Parse(path) + if err != nil { + return err + } + if pt.Name == f.parent.Name { + return nil + } + // if f.parent.Name != "/" { + info = fs.WithName(strings.TrimPrefix(info.Name(), f.parent.Name), info) + // } + infos = append(infos, info) + return nil + }) + + if err != nil { + if _, ok := err.(*os.PathError); ok { + return infos, nil + } + if err != io.EOF { + return nil, err + } + } + return infos, nil + +} + +func (f *File) Open(name string) (http.File, error) { + pt, err := f.fs.Parse(name) + if err != nil { + return nil, err + } + + if pt == f.path { + return f, nil + } + + pt.Name = path.Join(f.Path().Name, pt.Name) + + di, err := f.fs.Open(pt.String()) + if err != nil { + return nil, err + } + + fi, err := di.Stat() + if err != nil { + return nil, err + } + if fi.IsDir() { + d2 := &File{ + info: fs.NewFileInfo(fi), + her: di.Info(), + path: pt, + parent: f.path, + fs: f.fs, + } + di = d2 + } + return di, nil +} diff --git a/fs/memfs/file_test.go b/fs/memfs/file_test.go new file mode 100644 index 0000000..73e9552 --- /dev/null +++ b/fs/memfs/file_test.go @@ -0,0 +1,70 @@ +package memfs + +import ( + "bytes" + "io" + "io/ioutil" + "strings" + "testing" + "time" + + "github.com/markbates/pkger/here" + "github.com/stretchr/testify/require" +) + +func Test_File_Read_Memory(t *testing.T) { + r := require.New(t) + + fs, err := New(here.Info{}) + r.NoError(err) + + f, err := fs.Create("/file_test.go") + r.NoError(err) + _, err = io.Copy(f, bytes.NewReader([]byte("hi!"))) + r.NoError(err) + r.NoError(f.Close()) + + f, err = fs.Open("/file_test.go") + r.NoError(err) + fi, err := f.Stat() + r.NoError(err) + r.Equal("/file_test.go", fi.Name()) + + b, err := ioutil.ReadAll(f) + r.NoError(err) + r.Equal(string(b), "hi!") +} + +func Test_File_Write(t *testing.T) { + r := require.New(t) + + fs, err := New(here.Info{}) + r.NoError(err) + + f, err := fs.Create("/hello.txt") + r.NoError(err) + r.NotNil(f) + + fi, err := f.Stat() + r.NoError(err) + r.Zero(fi.Size()) + + r.Equal("/hello.txt", fi.Name()) + + mt := fi.ModTime() + r.NotZero(mt) + + sz, err := io.Copy(f, strings.NewReader(radio)) + r.NoError(err) + r.Equal(int64(1381), sz) + + // because windows can't handle the time precisely + // enough, we have to *force* just a smidge of time + // to ensure the two ModTime's are different. + // i know, i hate it too. + time.Sleep(time.Millisecond) + r.NoError(f.Close()) + r.Equal(int64(1381), fi.Size()) + r.NotZero(fi.ModTime()) + r.NotEqual(mt, fi.ModTime()) +} diff --git a/fs/memfs/http.go b/fs/memfs/http.go new file mode 100644 index 0000000..8151e03 --- /dev/null +++ b/fs/memfs/http.go @@ -0,0 +1 @@ +package memfs diff --git a/fs/memfs/http_test.go b/fs/memfs/http_test.go new file mode 100644 index 0000000..1dbf8b6 --- /dev/null +++ b/fs/memfs/http_test.go @@ -0,0 +1,84 @@ +package memfs + +import ( + "io/ioutil" + "net/http" + "net/http/httptest" + "testing" + + "github.com/stretchr/testify/require" +) + +func Test_HTTP_Dir(t *testing.T) { + r := require.New(t) + + fs := NewFS() + + r.NoError(Folder.Create(fs)) + + dir, err := fs.Open("/") + r.NoError(err) + ts := httptest.NewServer(http.FileServer(dir)) + defer ts.Close() + + res, err := http.Get(ts.URL + "/") + r.NoError(err) + r.Equal(200, res.StatusCode) + + b, err := ioutil.ReadAll(res.Body) + r.NoError(err) + r.Contains(string(b), `/public/images/mark.png`) +} + +func Test_HTTP_File_Memory(t *testing.T) { + r := require.New(t) + + fs := NewFS() + r.NoError(Folder.Create(fs)) + + dir, err := fs.Open("/") + r.NoError(err) + ts := httptest.NewServer(http.FileServer(dir)) + defer ts.Close() + + res, err := http.Get(ts.URL + "/public/images/mark.png") + r.NoError(err) + r.Equal(200, res.StatusCode) + + b, err := ioutil.ReadAll(res.Body) + r.NoError(err) + r.Contains(string(b), `!/public/images/mark.png`) +} + +func Test_HTTP_Dir_Memory_StripPrefix(t *testing.T) { + r := require.New(t) + + fs := NewFS() + r.NoError(Folder.Create(fs)) + + dir, err := fs.Open("/public") + r.NoError(err) + defer dir.Close() + + ts := httptest.NewServer(http.StripPrefix("/assets/", http.FileServer(dir))) + defer ts.Close() + + res, err := http.Get(ts.URL + "/assets/images/mark.png") + r.NoError(err) + r.Equal(200, res.StatusCode) + + b, _ := ioutil.ReadAll(res.Body) + // r.NoError(err) + r.Contains(string(b), "!/public/images/mark.png") + + res, err = http.Get(ts.URL + "/assets/images/") + r.NoError(err) + r.Equal(200, res.StatusCode) + + b, _ = ioutil.ReadAll(res.Body) + // r.NoError(err) + r.Contains(string(b), `/mark.png`) + r.NotContains(string(b), `/public`) + r.NotContains(string(b), `/images`) + r.NotContains(string(b), `/go.mod`) +} diff --git a/fs/memfs/json.go b/fs/memfs/json.go new file mode 100644 index 0000000..31bb74d --- /dev/null +++ b/fs/memfs/json.go @@ -0,0 +1,66 @@ +package memfs + +import ( + "encoding/json" + "fmt" + + "github.com/markbates/pkger/fs" +) + +func (f File) MarshalJSON() ([]byte, error) { + m := map[string]interface{}{ + "info": f.info, + "her": f.her, + "path": f.path, + "data": f.data, + "parent": f.parent, + } + return json.Marshal(m) +} + +func (f *File) UnmarshalJSON(b []byte) error { + m := map[string]json.RawMessage{} + if err := json.Unmarshal(b, &m); err != nil { + return err + } + + info, ok := m["info"] + if !ok { + return fmt.Errorf("missing info") + } + + f.info = &fs.FileInfo{} + if err := json.Unmarshal(info, f.info); err != nil { + return err + } + + her, ok := m["her"] + if !ok { + return fmt.Errorf("missing her") + } + if err := json.Unmarshal(her, &f.her); err != nil { + return err + } + + path, ok := m["path"] + if !ok { + return fmt.Errorf("missing path") + } + if err := json.Unmarshal(path, &f.path); err != nil { + return err + } + + parent, ok := m["parent"] + if !ok { + return fmt.Errorf("missing parent") + } + if err := json.Unmarshal(parent, &f.parent); err != nil { + return err + } + + if err := json.Unmarshal(m["data"], &f.data); err != nil { + return err + } + + return nil +} diff --git a/fs/memfs/json_test.go b/fs/memfs/json_test.go new file mode 100644 index 0000000..9ba7487 --- /dev/null +++ b/fs/memfs/json_test.go @@ -0,0 +1,43 @@ +package memfs + +import ( + "encoding/json" + "io" + "strings" + "testing" + + "github.com/markbates/pkger/here" + "github.com/stretchr/testify/require" +) + +func Test_File_JSON(t *testing.T) { + r := require.New(t) + + fs, err := New(here.Info{}) + r.NoError(err) + + f, err := fs.Create("/radio.radio") + r.NoError(err) + _, err = io.Copy(f, strings.NewReader(radio)) + r.NoError(err) + r.NoError(f.Close()) + + f, err = fs.Open("/radio.radio") + r.NoError(err) + bi, err := f.Stat() + r.NoError(err) + + mj, err := json.Marshal(f) + r.NoError(err) + + f2 := &File{} + + r.NoError(json.Unmarshal(mj, f2)) + + ai, err := f2.Stat() + r.NoError(err) + + r.Equal(bi.Size(), ai.Size()) + + r.Equal(radio, string(f2.data)) +} diff --git a/fs/memfs/memfs.go b/fs/memfs/memfs.go new file mode 100644 index 0000000..f88065b --- /dev/null +++ b/fs/memfs/memfs.go @@ -0,0 +1,58 @@ +package memfs + +import ( + "io/ioutil" + + "github.com/markbates/pkger/fs" + "github.com/markbates/pkger/here" + "github.com/markbates/pkger/internal/maps" +) + +var _ fs.FileSystem = &FS{} + +func New(info here.Info) (*FS, error) { + f := &FS{ + infos: &maps.Infos{}, + paths: &maps.Paths{}, + files: &maps.Files{}, + } + return f, nil +} + +type FS struct { + infos *maps.Infos + paths *maps.Paths + files *maps.Files + current here.Info +} + +func (f *FS) Current() (here.Info, error) { + return f.current, nil +} + +func (f *FS) Info(p string) (here.Info, error) { + info, ok := f.infos.Load(p) + if ok { + return info, nil + } + + info, err := here.Package(p) + if err != nil { + return info, err + } + f.infos.Store(p, info) + return info, nil +} + +func (f *FS) Parse(p string) (fs.Path, error) { + return f.paths.Parse(p) +} + +func (fx *FS) ReadFile(s string) ([]byte, error) { + f, err := fx.Open(s) + if err != nil { + return nil, err + } + defer f.Close() + return ioutil.ReadAll(f) +} diff --git a/fs/memfs/memfs_test.go b/fs/memfs/memfs_test.go new file mode 100644 index 0000000..fbfc5e3 --- /dev/null +++ b/fs/memfs/memfs_test.go @@ -0,0 +1,26 @@ +package memfs + +import ( + "log" + + "github.com/markbates/pkger/fs/fstest" + "github.com/markbates/pkger/here" +) + +func NewFS() *FS { + fs, err := New(here.Info{}) + if err != nil { + log.Fatal(err) + } + return fs +} + +var Folder = fstest.TestFiles{ + "/main.go": {Data: []byte("!/main.go")}, + "/go.mod": {Data: []byte("!/go.mod")}, + "/go.sum": {Data: []byte("!/go.sum")}, + "/public/index.html": {Data: []byte("!/public/index.html")}, + "/public/images/mark.png": {Data: []byte("!/public/images/mark.png")}, + "/templates/a.txt": {Data: []byte("!/templates/a.txt")}, + "/templates/b/b.txt": {Data: []byte("!/templates/b/b.txt")}, +} diff --git a/fs/memfs/mkdirall.go b/fs/memfs/mkdirall.go new file mode 100644 index 0000000..1cd5c43 --- /dev/null +++ b/fs/memfs/mkdirall.go @@ -0,0 +1,61 @@ +package memfs + +import ( + "os" + "path/filepath" + "time" + + "github.com/markbates/pkger/fs" +) + +func (fx *FS) MkdirAll(p string, perm os.FileMode) error { + path, err := fx.Parse(p) + if err != nil { + return err + } + root := path.Name + + cur, err := fx.Current() + if err != nil { + return err + } + for root != "" { + pt := fs.Path{ + Pkg: path.Pkg, + Name: root, + } + if _, ok := fx.files.Load(pt); ok { + root = filepath.Dir(root) + if root == "/" || root == "\\" { + break + } + continue + } + f := &File{ + fs: fx, + path: pt, + her: cur, + info: &fs.FileInfo{ + Details: fs.Details{ + Name: pt.Name, + Mode: perm, + ModTime: fs.ModTime(time.Now()), + }, + }, + } + + if err != nil { + return err + } + f.info.Details.IsDir = true + f.info.Details.Mode = perm + if err := f.Close(); err != nil { + return err + } + fx.files.Store(pt, f) + root = filepath.Dir(root) + } + + return nil + +} diff --git a/fs/memfs/mkdirall_test.go b/fs/memfs/mkdirall_test.go new file mode 100644 index 0000000..a9da153 --- /dev/null +++ b/fs/memfs/mkdirall_test.go @@ -0,0 +1,25 @@ +package memfs + +import ( + "os" + "testing" + + "github.com/markbates/pkger/here" + "github.com/stretchr/testify/require" +) + +func Test_MkdirAll(t *testing.T) { + r := require.New(t) + + fs, _ := New(here.Info{}) + + err := fs.MkdirAll("/foo/bar/baz", 0755) + r.NoError(err) + + fi, err := fs.Stat("/foo/bar/baz") + r.NoError(err) + + r.Equal("/foo/bar/baz", fi.Name()) + r.Equal(os.FileMode(0755), fi.Mode()) + r.True(fi.IsDir()) +} diff --git a/fs/memfs/open.go b/fs/memfs/open.go new file mode 100644 index 0000000..78f27d6 --- /dev/null +++ b/fs/memfs/open.go @@ -0,0 +1,32 @@ +package memfs + +import ( + "fmt" + + "github.com/markbates/pkger/fs" +) + +func (fx *FS) Open(name string) (fs.File, error) { + pt, err := fx.Parse(name) + if err != nil { + return nil, err + } + + fl, ok := fx.files.Load(pt) + if !ok { + return nil, fmt.Errorf("could not open %s", name) + } + f, ok := fl.(*File) + if !ok { + return nil, fmt.Errorf("could not open %s", name) + } + nf := &File{ + fs: fx, + info: fs.WithName(f.info.Name(), f.info), + path: f.path, + data: f.data, + her: f.her, + } + + return nf, nil +} diff --git a/fs/memfs/open_test.go b/fs/memfs/open_test.go new file mode 100644 index 0000000..b173b08 --- /dev/null +++ b/fs/memfs/open_test.go @@ -0,0 +1,34 @@ +package memfs + +import ( + "io" + "io/ioutil" + "strings" + "testing" + + "github.com/markbates/pkger/here" + "github.com/stretchr/testify/require" +) + +func Test_Open(t *testing.T) { + r := require.New(t) + + fs, err := New(here.Info{}) + r.NoError(err) + + _, err = fs.Open("/i.dont.exist") + r.Error(err) + + f, err := fs.Create("/i.exist") + r.NoError(err) + _, err = io.Copy(f, strings.NewReader(radio)) + r.NoError(err) + r.NoError(f.Close()) + + f, err = fs.Open("/i.exist") + r.NoError(err) + b, err := ioutil.ReadAll(f) + r.NoError(err) + r.NoError(f.Close()) + r.Equal([]byte(radio), b) +} diff --git a/fs/memfs/stat.go b/fs/memfs/stat.go new file mode 100644 index 0000000..67f702f --- /dev/null +++ b/fs/memfs/stat.go @@ -0,0 +1,18 @@ +package memfs + +import ( + "fmt" + "os" +) + +func (fx *FS) Stat(name string) (os.FileInfo, error) { + pt, err := fx.Parse(name) + if err != nil { + return nil, err + } + f, ok := fx.files.Load(pt) + if ok { + return f.Stat() + } + return nil, fmt.Errorf("could not stat %s", name) +} diff --git a/fs/memfs/stat_test.go b/fs/memfs/stat_test.go new file mode 100644 index 0000000..d6aa990 --- /dev/null +++ b/fs/memfs/stat_test.go @@ -0,0 +1,25 @@ +package memfs + +import ( + "testing" + + "github.com/markbates/pkger/here" + "github.com/stretchr/testify/require" +) + +func Test_Stat(t *testing.T) { + r := require.New(t) + + fs, err := New(here.Info{}) + r.NoError(err) + _, err = fs.Stat("/i.dont.exist") + r.Error(err) + + f, err := fs.Create("/i.exist") + r.NoError(err) + r.NoError(f.Close()) + + fi, err := fs.Stat("/i.exist") + r.NoError(err) + r.Equal("/i.exist", fi.Name()) +} diff --git a/fs/memfs/walk.go b/fs/memfs/walk.go new file mode 100644 index 0000000..015acd5 --- /dev/null +++ b/fs/memfs/walk.go @@ -0,0 +1,38 @@ +package memfs + +import ( + "fmt" + "path/filepath" + "strings" + + "github.com/markbates/pkger/fs" +) + +func (f *FS) Walk(p string, wf filepath.WalkFunc) error { + keys := f.files.Keys() + + pt, err := f.Parse(p) + if err != nil { + return err + } + for _, k := range keys { + if !strings.HasPrefix(k.Name, pt.Name) { + continue + } + fl, ok := f.files.Load(k) + if !ok { + return fmt.Errorf("could not find %s", k) + } + fi, err := fl.Stat() + if err != nil { + return err + } + + fi = fs.WithName(strings.TrimPrefix(k.Name, pt.Name), fi) + err = wf(k.String(), fi, nil) + if err != nil { + return err + } + } + return nil +} diff --git a/fs/memfs/walk_test.go b/fs/memfs/walk_test.go new file mode 100644 index 0000000..aa56657 --- /dev/null +++ b/fs/memfs/walk_test.go @@ -0,0 +1,69 @@ +package memfs + +import ( + "io" + "os" + "sort" + "strings" + "testing" + + "github.com/markbates/pkger/here" + "github.com/stretchr/testify/require" +) + +func Test_Walk(t *testing.T) { + r := require.New(t) + + files := []struct { + name string + body string + }{ + {name: "/a/a.txt", body: "A"}, + {name: "/a/a.md", body: "Amd"}, + {name: "/b/c/d.txt", body: "B"}, + {name: "/f.txt", body: "F"}, + } + + sort.Slice(files, func(a, b int) bool { + return files[a].name < files[b].name + }) + + fs, err := New(here.Info{}) + r.NoError(err) + + for _, file := range files { + f, err := fs.Create(file.name) + r.NoError(err) + _, err = io.Copy(f, strings.NewReader(file.body)) + r.NoError(err) + r.NoError(f.Close()) + } + + var found []string + err = fs.Walk("/", func(path string, info os.FileInfo, err error) error { + if err != nil { + return err + } + + found = append(found, path) + return nil + }) + r.NoError(err) + + expected := []string{":/", ":/a", ":/a/a.md", ":/a/a.txt", ":/b", ":/b/c", ":/b/c/d.txt", ":/f.txt"} + r.Equal(expected, found) + + found = []string{} + err = fs.Walk("/a/", func(path string, info os.FileInfo, err error) error { + if err != nil { + return err + } + + found = append(found, path) + return nil + }) + r.NoError(err) + + expected = []string{":/a/a.md", ":/a/a.txt"} + r.Equal(expected, found) +} diff --git a/fs/path.go b/fs/path.go new file mode 100644 index 0000000..902c31e --- /dev/null +++ b/fs/path.go @@ -0,0 +1,39 @@ +package fs + +import ( + "encoding/json" + "fmt" + "os" +) + +type Path struct { + Pkg string `json:"pkg"` + Name string `json:"name"` +} + +func (p Path) String() string { + if p.Name == "" { + p.Name = "/" + } + return fmt.Sprintf("%s:%s", p.Pkg, p.Name) +} + +func (p Path) Format(st fmt.State, verb rune) { + switch verb { + case 'v': + if st.Flag('+') { + b, err := json.MarshalIndent(p, "", " ") + if err != nil { + fmt.Fprint(os.Stderr, err) + return + } + fmt.Fprint(st, string(b)) + return + } + fmt.Fprint(st, p.String()) + case 'q': + fmt.Fprintf(st, "%q", p.String()) + default: + fmt.Fprint(st, p.String()) + } +} diff --git a/internal/maps/files.go b/internal/maps/files.go new file mode 100644 index 0000000..c30170f --- /dev/null +++ b/internal/maps/files.go @@ -0,0 +1,146 @@ +// Code generated by github.com/gobuffalo/mapgen. DO NOT EDIT. + +package maps + +import ( + "encoding/json" + "fmt" + "sort" + "sync" + + "github.com/markbates/pkger/fs" +) + +// Files wraps sync.Map and uses the following types: +// key: fs.Path +// value: fs.File +type Files struct { + data *sync.Map + once *sync.Once +} + +func (m *Files) Data() *sync.Map { + if m.once == nil { + m.once = &sync.Once{} + } + m.once.Do(func() { + if m.data == nil { + m.data = &sync.Map{} + } + }) + return m.data +} + +func (m *Files) MarshalJSON() ([]byte, error) { + var err error + mm := map[string]interface{}{} + m.Data().Range(func(key, value interface{}) bool { + var b []byte + b, err = json.Marshal(key) + if err != nil { + return false + } + mm[string(b)] = value + return true + }) + + if err != nil { + return nil, err + } + + return json.Marshal(mm) +} + +func (m *Files) UnmarshalJSON(b []byte) error { + mm := map[string]fs.File{} + + if err := json.Unmarshal(b, &mm); err != nil { + return err + } + for k, v := range mm { + var pt fs.Path + if err := json.Unmarshal([]byte(k), &pt); err != nil { + return err + } + m.Store(pt, v) + } + return nil +} + +// Delete the key from the map +func (m *Files) Delete(key fs.Path) { + m.Data().Delete(key) +} + +// Load the key from the map. +// Returns fs.File or bool. +// A false return indicates either the key was not found +// or the value is not of type fs.File +func (m *Files) Load(key fs.Path) (fs.File, bool) { + i, ok := m.Data().Load(key) + if !ok { + return nil, false + } + s, ok := i.(fs.File) + return s, ok +} + +// LoadOrStore will return an existing key or +// store the value if not already in the map +func (m *Files) LoadOrStore(key fs.Path, value fs.File) (fs.File, bool) { + i, _ := m.Data().LoadOrStore(key, value) + s, ok := i.(fs.File) + return s, ok +} + +// LoadOr will return an existing key or +// run the function and store the results +func (m *Files) LoadOr(key fs.Path, fn func(*Files) (fs.File, bool)) (fs.File, bool) { + i, ok := m.Load(key) + if ok { + return i, ok + } + i, ok = fn(m) + if ok { + m.Store(key, i) + return i, ok + } + return i, false +} + +// Range over the fs.File values in the map +func (m *Files) Range(f func(key fs.Path, value fs.File) bool) { + m.Data().Range(func(k, v interface{}) bool { + key, ok := k.(fs.Path) + if !ok { + return false + } + value, ok := v.(fs.File) + if !ok { + return false + } + return f(key, value) + }) +} + +// Store a fs.File in the map +func (m *Files) Store(key fs.Path, value fs.File) { + m.Data().Store(key, value) +} + +// Keys returns a list of keys in the map +func (m *Files) Keys() []fs.Path { + var keys []fs.Path + m.Range(func(key fs.Path, value fs.File) bool { + keys = append(keys, key) + return true + }) + sort.Slice(keys, func(a, b int) bool { + return keys[a].String() <= keys[b].String() + }) + return keys +} + +func (m *Files) String() string { + return fmt.Sprintf("%v", m.Keys()) +} diff --git a/internal/maps/infos.go b/internal/maps/infos.go new file mode 100644 index 0000000..a0d4871 --- /dev/null +++ b/internal/maps/infos.go @@ -0,0 +1,126 @@ +// Code generated by github.com/markbates/pkger/mapgen. DO NOT EDIT. + +package maps + +import ( + "encoding/json" + "fmt" + "sort" + "sync" + + "github.com/markbates/pkger/here" +) + +// Infos wraps sync.Map and uses the following types: +// key: string +// value: here.Info +type Infos struct { + data *sync.Map + once *sync.Once +} + +func (m *Infos) Data() *sync.Map { + if m.once == nil { + m.once = &sync.Once{} + } + m.once.Do(func() { + if m.data == nil { + m.data = &sync.Map{} + } + }) + return m.data +} + +func (m *Infos) MarshalJSON() ([]byte, error) { + mm := map[string]interface{}{} + m.data.Range(func(key, value interface{}) bool { + mm[fmt.Sprintf("%s", key)] = value + return true + }) + return json.Marshal(mm) +} + +func (m *Infos) UnmarshalJSON(b []byte) error { + mm := map[string]here.Info{} + + if err := json.Unmarshal(b, &mm); err != nil { + return err + } + for k, v := range mm { + m.Store(k, v) + } + return nil +} + +// Delete the key from the map +func (m *Infos) Delete(key string) { + m.Data().Delete(key) +} + +// Load the key from the map. +// Returns here.Info or bool. +// A false return indicates either the key was not found +// or the value is not of type here.Info +func (m *Infos) Load(key string) (here.Info, bool) { + m.Data() + i, ok := m.data.Load(key) + if !ok { + return here.Info{}, false + } + s, ok := i.(here.Info) + return s, ok +} + +// LoadOrStore will return an existing key or +// store the value if not already in the map +func (m *Infos) LoadOrStore(key string, value here.Info) (here.Info, bool) { + i, _ := m.Data().LoadOrStore(key, value) + s, ok := i.(here.Info) + return s, ok +} + +// LoadOr will return an existing key or +// run the function and store the results +func (m *Infos) LoadOr(key string, fn func(*Infos) (here.Info, bool)) (here.Info, bool) { + i, ok := m.Load(key) + if ok { + return i, ok + } + i, ok = fn(m) + if ok { + m.Store(key, i) + return i, ok + } + return i, false +} + +// Range over the here.Info values in the map +func (m *Infos) Range(f func(key string, value here.Info) bool) { + m.Data().Range(func(k, v interface{}) bool { + key, ok := k.(string) + if !ok { + return false + } + value, ok := v.(here.Info) + if !ok { + return false + } + return f(key, value) + }) +} + +// Store a here.Info in the map +func (m *Infos) Store(key string, value here.Info) { + m.Data().Store(key, value) +} + +// Keys returns a list of keys in the map +func (m *Infos) Keys() []string { + var keys []string + m.Range(func(key string, value here.Info) bool { + keys = append(keys, key) + return true + }) + sort.Strings(keys) + return keys +} diff --git a/internal/maps/paths.go b/internal/maps/paths.go new file mode 100644 index 0000000..356bec9 --- /dev/null +++ b/internal/maps/paths.go @@ -0,0 +1,182 @@ +// Code generated by github.com/gobuffalo/mapgen. DO NOT EDIT. + +package maps + +import ( + "encoding/json" + "fmt" + "regexp" + "sort" + "strings" + "sync" + + "github.com/markbates/pkger/fs" + "github.com/markbates/pkger/here" +) + +// Paths wraps sync.Map and uses the following types: +// key: string +// value: Path +type Paths struct { + Current here.Info + data *sync.Map + once *sync.Once +} + +func (m *Paths) Data() *sync.Map { + if m.once == nil { + m.once = &sync.Once{} + } + m.once.Do(func() { + if m.data == nil { + m.data = &sync.Map{} + } + }) + return m.data +} + +func (m *Paths) MarshalJSON() ([]byte, error) { + mm := map[string]interface{}{} + m.Data().Range(func(key, value interface{}) bool { + mm[fmt.Sprintf("%s", key)] = value + return true + }) + return json.Marshal(mm) +} + +func (m *Paths) UnmarshalJSON(b []byte) error { + mm := map[string]fs.Path{} + + if err := json.Unmarshal(b, &mm); err != nil { + return err + } + for k, v := range mm { + m.Store(k, v) + } + return nil +} + +// Delete the key from the map +func (m *Paths) Delete(key string) { + m.Data().Delete(key) +} + +// Load the key from the map. +// Returns Path or bool. +// A false return indicates either the key was not found +// or the value is not of type Path +func (m *Paths) Load(key string) (fs.Path, bool) { + i, ok := m.Data().Load(key) + if !ok { + return fs.Path{}, false + } + s, ok := i.(fs.Path) + return s, ok +} + +// LoadOrStore will return an existing key or +// store the value if not already in the map +func (m *Paths) LoadOrStore(key string, value fs.Path) (fs.Path, bool) { + i, _ := m.Data().LoadOrStore(key, value) + s, ok := i.(fs.Path) + return s, ok +} + +// LoadOr will return an existing key or +// run the function and store the results +func (m *Paths) LoadOr(key string, fn func(*Paths) (fs.Path, bool)) (fs.Path, bool) { + i, ok := m.Load(key) + if ok { + return i, ok + } + i, ok = fn(m) + if ok { + m.Store(key, i) + return i, ok + } + return i, false +} + +// Range over the Path values in the map +func (m *Paths) Range(f func(key string, value fs.Path) bool) { + m.Data().Range(func(k, v interface{}) bool { + key, ok := k.(string) + if !ok { + return false + } + value, ok := v.(fs.Path) + if !ok { + return false + } + return f(key, value) + }) +} + +// Store a Path in the map +func (m *Paths) Store(key string, value fs.Path) { + m.Data().Store(key, value) +} + +// Keys returns a list of keys in the map +func (m *Paths) Keys() []string { + var keys []string + m.Range(func(key string, value fs.Path) bool { + keys = append(keys, key) + return true + }) + sort.Strings(keys) + return keys +} + +func (m *Paths) Parse(p string) (fs.Path, error) { + p = strings.Replace(p, "\\", "/", -1) + pt, ok := m.Load(p) + if ok { + return pt, nil + } + if len(p) == 0 { + return m.build(p, "", "") + } + + res := pathrx.FindAllStringSubmatch(p, -1) + if len(res) == 0 { + return pt, fmt.Errorf("could not parse %q", p) + } + + matches := res[0] + + if len(matches) != 4 { + return pt, fmt.Errorf("could not parse %q", p) + } + + return m.build(p, matches[1], matches[3]) +} + +var pathrx = regexp.MustCompile("([^:]+)(:(/.+))?") + +func (m *Paths) build(p, pkg, name string) (fs.Path, error) { + pt := fs.Path{ + Pkg: pkg, + Name: name, + } + + if strings.HasPrefix(pt.Pkg, "/") || len(pt.Pkg) == 0 { + pt.Name = pt.Pkg + pt.Pkg = m.Current.ImportPath + } + + if len(pt.Name) == 0 { + pt.Name = "/" + } + + if pt.Pkg == pt.Name { + pt.Pkg = m.Current.ImportPath + pt.Name = "/" + } + + if !strings.HasPrefix(pt.Name, "/") { + pt.Name = "/" + pt.Name + } + m.Store(p, pt) + return pt, nil +} From aea42c035f6c1651500cfbb41ef248ae42dd24b4 Mon Sep 17 00:00:00 2001 From: Mark Bates Date: Sat, 31 Aug 2019 17:14:03 -0400 Subject: [PATCH 02/46] blind lemon --- fs/hdfs/create_test.go | 91 ++++++++++++++++++++++++++++++++++++++++ fs/hdfs/file_test.go | 67 +++++++++++++++++++++++++++++ fs/hdfs/hdfs_test.go | 23 ++++++++++ fs/hdfs/hello.txt | 0 fs/hdfs/http_test.go | 84 +++++++++++++++++++++++++++++++++++++ fs/hdfs/i.exist | 0 fs/hdfs/json_test.go | 44 +++++++++++++++++++ fs/hdfs/mkdirall_test.go | 23 ++++++++++ fs/hdfs/open_test.go | 32 ++++++++++++++ fs/hdfs/radio.radio | 0 fs/hdfs/stat_test.go | 24 +++++++++++ fs/hdfs/walk_test.go | 67 +++++++++++++++++++++++++++++ 12 files changed, 455 insertions(+) create mode 100644 fs/hdfs/create_test.go create mode 100644 fs/hdfs/file_test.go create mode 100644 fs/hdfs/hdfs_test.go create mode 100644 fs/hdfs/hello.txt create mode 100644 fs/hdfs/http_test.go create mode 100644 fs/hdfs/i.exist create mode 100644 fs/hdfs/json_test.go create mode 100644 fs/hdfs/mkdirall_test.go create mode 100644 fs/hdfs/open_test.go create mode 100644 fs/hdfs/radio.radio create mode 100644 fs/hdfs/stat_test.go create mode 100644 fs/hdfs/walk_test.go diff --git a/fs/hdfs/create_test.go b/fs/hdfs/create_test.go new file mode 100644 index 0000000..6b701b2 --- /dev/null +++ b/fs/hdfs/create_test.go @@ -0,0 +1,91 @@ +package hdfs + +import ( + "io" + "os" + "strings" + "testing" + + "github.com/stretchr/testify/require" +) + +func Test_Create(t *testing.T) { + r := require.New(t) + + fs := NewFS() + + f, err := fs.Create("/hello.txt") + r.NoError(err) + r.NotNil(f) + + fi, err := f.Stat() + r.NoError(err) + + r.Equal("/hello.txt", fi.Name()) + r.Equal(os.FileMode(0666), fi.Mode()) + r.NotZero(fi.ModTime()) +} + +func Test_Create_Write(t *testing.T) { + r := require.New(t) + + fs := NewFS() + + f, err := fs.Create("/hello.txt") + r.NoError(err) + r.NotNil(f) + + fi, err := f.Stat() + r.NoError(err) + r.Zero(fi.Size()) + + r.Equal("/hello.txt", fi.Name()) + + mt := fi.ModTime() + r.NotZero(mt) + + sz, err := io.Copy(f, strings.NewReader(radio)) + r.NoError(err) + r.Equal(int64(1381), sz) + + r.NoError(f.Close()) + r.Equal(int64(1381), fi.Size()) + r.NotZero(fi.ModTime()) + r.NotEqual(mt, fi.ModTime()) +} + +const radio = `I was tuning in the shine on the late night dial +Doing anything my radio advised +With every one of those late night stations +Playing songs bringing tears to my eyes +I was seriously thinking about hiding the receiver +When the switch broke 'cause it's old +They're saying things that I can hardly believe +They really think we're getting out of control +Radio is a sound salvation +Radio is cleaning up the nation +They say you better listen to the voice of reason +But they don't give you any choice 'cause they think that it's treason +So you had better do as you are told +You better listen to the radio +I wanna bite the hand that feeds me +I wanna bite that hand so badly +I want to make them wish they'd never seen me +Some of my friends sit around every evening +And they worry about the times ahead +But everybody else is overwhelmed by indifference +And the promise of an early bed +You either shut up or get cut up; they don't wanna hear about it +It's only inches on the reel-to-reel +And the radio is in the hands of such a lot of fools +Tryin' to anesthetize the way that you feel +Radio is a sound salvation +Radio is cleaning up the nation +They say you better listen to the voice of reason +But they don't give you any choice 'cause they think that it's treason +So you had better do as you are told +You better listen to the radio +Wonderful radio +Marvelous radio +Wonderful radio +Radio, radio` diff --git a/fs/hdfs/file_test.go b/fs/hdfs/file_test.go new file mode 100644 index 0000000..7c6ca0f --- /dev/null +++ b/fs/hdfs/file_test.go @@ -0,0 +1,67 @@ +package hdfs + +import ( + "bytes" + "io" + "io/ioutil" + "strings" + "testing" + "time" + + "github.com/stretchr/testify/require" +) + +func Test_File_Read_Memory(t *testing.T) { + r := require.New(t) + + fs := NewFS() + + f, err := fs.Create("/file_test.go") + r.NoError(err) + _, err = io.Copy(f, bytes.NewReader([]byte("hi!"))) + r.NoError(err) + r.NoError(f.Close()) + + f, err = fs.Open("/file_test.go") + r.NoError(err) + fi, err := f.Stat() + r.NoError(err) + r.Equal("/file_test.go", fi.Name()) + + b, err := ioutil.ReadAll(f) + r.NoError(err) + r.Equal(string(b), "hi!") +} + +func Test_File_Write(t *testing.T) { + r := require.New(t) + + fs := NewFS() + + f, err := fs.Create("/hello.txt") + r.NoError(err) + r.NotNil(f) + + fi, err := f.Stat() + r.NoError(err) + r.Zero(fi.Size()) + + r.Equal("/hello.txt", fi.Name()) + + mt := fi.ModTime() + r.NotZero(mt) + + sz, err := io.Copy(f, strings.NewReader(radio)) + r.NoError(err) + r.Equal(int64(1381), sz) + + // because windows can't handle the time precisely + // enough, we have to *force* just a smidge of time + // to ensure the two ModTime's are different. + // i know, i hate it too. + time.Sleep(time.Millisecond) + r.NoError(f.Close()) + r.Equal(int64(1381), fi.Size()) + r.NotZero(fi.ModTime()) + r.NotEqual(mt, fi.ModTime()) +} diff --git a/fs/hdfs/hdfs_test.go b/fs/hdfs/hdfs_test.go new file mode 100644 index 0000000..6d52926 --- /dev/null +++ b/fs/hdfs/hdfs_test.go @@ -0,0 +1,23 @@ +package hdfs + +import ( + "log" + + "github.com/markbates/pkger/fs/fstest" +) + +func NewFS() *FS { + fs, err := New() + if err != nil { + log.Fatal(err) + } + return fs +} + +var Folder = fstest.TestFiles{ + "/testdata/hdfs_test/main.go": {Data: []byte("!/testdata/hdfs_test/main.go")}, + "/testdata/hdfs_test/public/index.html": {Data: []byte("!/testdata/hdfs_test/public/index.html")}, + "/testdata/hdfs_test/public/images/mark.png": {Data: []byte("!/testdata/hdfs_test/public/images/mark.png")}, + "/testdata/hdfs_test/templates/a.txt": {Data: []byte("!/testdata/hdfs_test/templates/a.txt")}, + "/testdata/hdfs_test/templates/b/b.txt": {Data: []byte("!/testdata/hdfs_test/templates/b/b.txt")}, +} diff --git a/fs/hdfs/hello.txt b/fs/hdfs/hello.txt new file mode 100644 index 0000000..e69de29 diff --git a/fs/hdfs/http_test.go b/fs/hdfs/http_test.go new file mode 100644 index 0000000..c97e85f --- /dev/null +++ b/fs/hdfs/http_test.go @@ -0,0 +1,84 @@ +package hdfs + +import ( + "io/ioutil" + "net/http" + "net/http/httptest" + "testing" + + "github.com/stretchr/testify/require" +) + +func Test_HTTP_Dir(t *testing.T) { + r := require.New(t) + + fs := NewFS() + + r.NoError(Folder.Create(fs)) + + dir, err := fs.Open("/") + r.NoError(err) + ts := httptest.NewServer(http.FileServer(dir)) + defer ts.Close() + + res, err := http.Get(ts.URL + "/") + r.NoError(err) + r.Equal(200, res.StatusCode) + + b, err := ioutil.ReadAll(res.Body) + r.NoError(err) + r.Contains(string(b), `/public/images/mark.png`) +} + +func Test_HTTP_File_Memory(t *testing.T) { + r := require.New(t) + + fs := NewFS() + r.NoError(Folder.Create(fs)) + + dir, err := fs.Open("/") + r.NoError(err) + ts := httptest.NewServer(http.FileServer(dir)) + defer ts.Close() + + res, err := http.Get(ts.URL + "/public/images/mark.png") + r.NoError(err) + r.Equal(200, res.StatusCode) + + b, err := ioutil.ReadAll(res.Body) + r.NoError(err) + r.Contains(string(b), `!/public/images/mark.png`) +} + +func Test_HTTP_Dir_Memory_StripPrefix(t *testing.T) { + r := require.New(t) + + fs := NewFS() + r.NoError(Folder.Create(fs)) + + dir, err := fs.Open("/public") + r.NoError(err) + defer dir.Close() + + ts := httptest.NewServer(http.StripPrefix("/assets/", http.FileServer(dir))) + defer ts.Close() + + res, err := http.Get(ts.URL + "/assets/images/mark.png") + r.NoError(err) + r.Equal(200, res.StatusCode) + + b, _ := ioutil.ReadAll(res.Body) + // r.NoError(err) + r.Contains(string(b), "!/public/images/mark.png") + + res, err = http.Get(ts.URL + "/assets/images/") + r.NoError(err) + r.Equal(200, res.StatusCode) + + b, _ = ioutil.ReadAll(res.Body) + // r.NoError(err) + r.Contains(string(b), `/mark.png`) + r.NotContains(string(b), `/public`) + r.NotContains(string(b), `/images`) + r.NotContains(string(b), `/go.mod`) +} diff --git a/fs/hdfs/i.exist b/fs/hdfs/i.exist new file mode 100644 index 0000000..e69de29 diff --git a/fs/hdfs/json_test.go b/fs/hdfs/json_test.go new file mode 100644 index 0000000..e569706 --- /dev/null +++ b/fs/hdfs/json_test.go @@ -0,0 +1,44 @@ +package hdfs + +import ( + "encoding/json" + "io" + "io/ioutil" + "strings" + "testing" + + "github.com/stretchr/testify/require" +) + +func Test_File_JSON(t *testing.T) { + r := require.New(t) + + fs := NewFS() + + f, err := fs.Create("/radio.radio") + r.NoError(err) + _, err = io.Copy(f, strings.NewReader(radio)) + r.NoError(err) + r.NoError(f.Close()) + + f, err = fs.Open("/radio.radio") + r.NoError(err) + bi, err := f.Stat() + r.NoError(err) + + mj, err := json.Marshal(f) + r.NoError(err) + + f2 := &File{} + + r.NoError(json.Unmarshal(mj, f2)) + + ai, err := f2.Stat() + r.NoError(err) + + r.Equal(bi.Size(), ai.Size()) + + fd, err := ioutil.ReadAll(f2) + r.NoError(err) + r.Equal(radio, string(fd)) +} diff --git a/fs/hdfs/mkdirall_test.go b/fs/hdfs/mkdirall_test.go new file mode 100644 index 0000000..2506dfc --- /dev/null +++ b/fs/hdfs/mkdirall_test.go @@ -0,0 +1,23 @@ +package hdfs + +import ( + "os" + "testing" + + "github.com/stretchr/testify/require" +) + +func Test_MkdirAll(t *testing.T) { + r := require.New(t) + + fs := NewFS() + err := fs.MkdirAll("/foo/bar/baz", 0755) + r.NoError(err) + + fi, err := fs.Stat("/foo/bar/baz") + r.NoError(err) + + r.Equal("/foo/bar/baz", fi.Name()) + r.Equal(os.FileMode(0755), fi.Mode()) + r.True(fi.IsDir()) +} diff --git a/fs/hdfs/open_test.go b/fs/hdfs/open_test.go new file mode 100644 index 0000000..2805825 --- /dev/null +++ b/fs/hdfs/open_test.go @@ -0,0 +1,32 @@ +package hdfs + +import ( + "io" + "io/ioutil" + "strings" + "testing" + + "github.com/stretchr/testify/require" +) + +func Test_Open(t *testing.T) { + r := require.New(t) + + fs := NewFS() + + _, err := fs.Open("/i.dont.exist") + r.Error(err) + + f, err := fs.Create("/i.exist") + r.NoError(err) + _, err = io.Copy(f, strings.NewReader(radio)) + r.NoError(err) + r.NoError(f.Close()) + + f, err = fs.Open("/i.exist") + r.NoError(err) + b, err := ioutil.ReadAll(f) + r.NoError(err) + r.NoError(f.Close()) + r.Equal([]byte(radio), b) +} diff --git a/fs/hdfs/radio.radio b/fs/hdfs/radio.radio new file mode 100644 index 0000000..e69de29 diff --git a/fs/hdfs/stat_test.go b/fs/hdfs/stat_test.go new file mode 100644 index 0000000..3ce3eaf --- /dev/null +++ b/fs/hdfs/stat_test.go @@ -0,0 +1,24 @@ +package hdfs + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func Test_Stat(t *testing.T) { + r := require.New(t) + + fs := NewFS() + + _, err := fs.Stat("/i.dont.exist") + r.Error(err) + + f, err := fs.Create("/i.exist") + r.NoError(err) + r.NoError(f.Close()) + + fi, err := fs.Stat("/i.exist") + r.NoError(err) + r.Equal("/i.exist", fi.Name()) +} diff --git a/fs/hdfs/walk_test.go b/fs/hdfs/walk_test.go new file mode 100644 index 0000000..61117e2 --- /dev/null +++ b/fs/hdfs/walk_test.go @@ -0,0 +1,67 @@ +package hdfs + +import ( + "io" + "os" + "sort" + "strings" + "testing" + + "github.com/stretchr/testify/require" +) + +func Test_Walk(t *testing.T) { + r := require.New(t) + + files := []struct { + name string + body string + }{ + {name: "/a/a.txt", body: "A"}, + {name: "/a/a.md", body: "Amd"}, + {name: "/b/c/d.txt", body: "B"}, + {name: "/f.txt", body: "F"}, + } + + sort.Slice(files, func(a, b int) bool { + return files[a].name < files[b].name + }) + + fs := NewFS() + + for _, file := range files { + f, err := fs.Create(file.name) + r.NoError(err) + _, err = io.Copy(f, strings.NewReader(file.body)) + r.NoError(err) + r.NoError(f.Close()) + } + + var found []string + err := fs.Walk("/", func(path string, info os.FileInfo, err error) error { + if err != nil { + return err + } + + found = append(found, path) + return nil + }) + r.NoError(err) + + expected := []string{":/", ":/a", ":/a/a.md", ":/a/a.txt", ":/b", ":/b/c", ":/b/c/d.txt", ":/f.txt"} + r.Equal(expected, found) + + found = []string{} + err = fs.Walk("/a/", func(path string, info os.FileInfo, err error) error { + if err != nil { + return err + } + + found = append(found, path) + return nil + }) + r.NoError(err) + + expected = []string{":/a/a.md", ":/a/a.txt"} + r.Equal(expected, found) +} From 91ee10f16bfe7440f32f17da9773d70eba2ea9cc Mon Sep 17 00:00:00 2001 From: Mark Bates Date: Sat, 31 Aug 2019 21:13:35 -0400 Subject: [PATCH 03/46] wrong --- fs/hdfs/create_test.go | 91 ------------------------------------- fs/hdfs/file.go | 9 +++- fs/hdfs/file_test.go | 67 --------------------------- fs/hdfs/hdfs.go | 27 ++--------- fs/hdfs/hdfs_test.go | 23 ---------- fs/hdfs/http_test.go | 84 ---------------------------------- fs/hdfs/json_test.go | 44 ------------------ fs/hdfs/mkdirall_test.go | 23 ---------- fs/hdfs/open_test.go | 32 ------------- fs/hdfs/stat_test.go | 24 ---------- fs/hdfs/walk_test.go | 67 --------------------------- testdata/public/radio.radio | 35 -------------- 12 files changed, 12 insertions(+), 514 deletions(-) delete mode 100644 fs/hdfs/create_test.go delete mode 100644 fs/hdfs/file_test.go delete mode 100644 fs/hdfs/hdfs_test.go delete mode 100644 fs/hdfs/http_test.go delete mode 100644 fs/hdfs/json_test.go delete mode 100644 fs/hdfs/mkdirall_test.go delete mode 100644 fs/hdfs/open_test.go delete mode 100644 fs/hdfs/stat_test.go delete mode 100644 fs/hdfs/walk_test.go delete mode 100644 testdata/public/radio.radio diff --git a/fs/hdfs/create_test.go b/fs/hdfs/create_test.go deleted file mode 100644 index 6b701b2..0000000 --- a/fs/hdfs/create_test.go +++ /dev/null @@ -1,91 +0,0 @@ -package hdfs - -import ( - "io" - "os" - "strings" - "testing" - - "github.com/stretchr/testify/require" -) - -func Test_Create(t *testing.T) { - r := require.New(t) - - fs := NewFS() - - f, err := fs.Create("/hello.txt") - r.NoError(err) - r.NotNil(f) - - fi, err := f.Stat() - r.NoError(err) - - r.Equal("/hello.txt", fi.Name()) - r.Equal(os.FileMode(0666), fi.Mode()) - r.NotZero(fi.ModTime()) -} - -func Test_Create_Write(t *testing.T) { - r := require.New(t) - - fs := NewFS() - - f, err := fs.Create("/hello.txt") - r.NoError(err) - r.NotNil(f) - - fi, err := f.Stat() - r.NoError(err) - r.Zero(fi.Size()) - - r.Equal("/hello.txt", fi.Name()) - - mt := fi.ModTime() - r.NotZero(mt) - - sz, err := io.Copy(f, strings.NewReader(radio)) - r.NoError(err) - r.Equal(int64(1381), sz) - - r.NoError(f.Close()) - r.Equal(int64(1381), fi.Size()) - r.NotZero(fi.ModTime()) - r.NotEqual(mt, fi.ModTime()) -} - -const radio = `I was tuning in the shine on the late night dial -Doing anything my radio advised -With every one of those late night stations -Playing songs bringing tears to my eyes -I was seriously thinking about hiding the receiver -When the switch broke 'cause it's old -They're saying things that I can hardly believe -They really think we're getting out of control -Radio is a sound salvation -Radio is cleaning up the nation -They say you better listen to the voice of reason -But they don't give you any choice 'cause they think that it's treason -So you had better do as you are told -You better listen to the radio -I wanna bite the hand that feeds me -I wanna bite that hand so badly -I want to make them wish they'd never seen me -Some of my friends sit around every evening -And they worry about the times ahead -But everybody else is overwhelmed by indifference -And the promise of an early bed -You either shut up or get cut up; they don't wanna hear about it -It's only inches on the reel-to-reel -And the radio is in the hands of such a lot of fools -Tryin' to anesthetize the way that you feel -Radio is a sound salvation -Radio is cleaning up the nation -They say you better listen to the voice of reason -But they don't give you any choice 'cause they think that it's treason -So you had better do as you are told -You better listen to the radio -Wonderful radio -Marvelous radio -Wonderful radio -Radio, radio` diff --git a/fs/hdfs/file.go b/fs/hdfs/file.go index 572e4cd..f2b366c 100644 --- a/fs/hdfs/file.go +++ b/fs/hdfs/file.go @@ -3,6 +3,7 @@ package hdfs import ( "net/http" "os" + "strings" "github.com/markbates/pkger/fs" "github.com/markbates/pkger/here" @@ -20,12 +21,16 @@ type File struct { } func NewFile(fx fs.FileSystem, osf *os.File) (*File, error) { - info, err := osf.Stat() + + cur, err := fx.Current() if err != nil { return nil, err } + pt := fs.Path{ + Name: strings.TrimPrefix(osf.Name(), cur.Dir), + } - pt, err := fx.Parse(info.Name()) + info, err := osf.Stat() if err != nil { return nil, err } diff --git a/fs/hdfs/file_test.go b/fs/hdfs/file_test.go deleted file mode 100644 index 7c6ca0f..0000000 --- a/fs/hdfs/file_test.go +++ /dev/null @@ -1,67 +0,0 @@ -package hdfs - -import ( - "bytes" - "io" - "io/ioutil" - "strings" - "testing" - "time" - - "github.com/stretchr/testify/require" -) - -func Test_File_Read_Memory(t *testing.T) { - r := require.New(t) - - fs := NewFS() - - f, err := fs.Create("/file_test.go") - r.NoError(err) - _, err = io.Copy(f, bytes.NewReader([]byte("hi!"))) - r.NoError(err) - r.NoError(f.Close()) - - f, err = fs.Open("/file_test.go") - r.NoError(err) - fi, err := f.Stat() - r.NoError(err) - r.Equal("/file_test.go", fi.Name()) - - b, err := ioutil.ReadAll(f) - r.NoError(err) - r.Equal(string(b), "hi!") -} - -func Test_File_Write(t *testing.T) { - r := require.New(t) - - fs := NewFS() - - f, err := fs.Create("/hello.txt") - r.NoError(err) - r.NotNil(f) - - fi, err := f.Stat() - r.NoError(err) - r.Zero(fi.Size()) - - r.Equal("/hello.txt", fi.Name()) - - mt := fi.ModTime() - r.NotZero(mt) - - sz, err := io.Copy(f, strings.NewReader(radio)) - r.NoError(err) - r.Equal(int64(1381), sz) - - // because windows can't handle the time precisely - // enough, we have to *force* just a smidge of time - // to ensure the two ModTime's are different. - // i know, i hate it too. - time.Sleep(time.Millisecond) - r.NoError(f.Close()) - r.Equal(int64(1381), fi.Size()) - r.NotZero(fi.ModTime()) - r.NotEqual(mt, fi.ModTime()) -} diff --git a/fs/hdfs/hdfs.go b/fs/hdfs/hdfs.go index 9d05773..3d4892d 100644 --- a/fs/hdfs/hdfs.go +++ b/fs/hdfs/hdfs.go @@ -36,6 +36,9 @@ func (fx *FS) Create(name string) (fs.File, error) { if err != nil { return nil, err } + if err := fx.MkdirAll(filepath.Dir(name), 0755); err != nil { + return nil, err + } f, err := os.Create(name) if err != nil { return nil, err @@ -66,6 +69,7 @@ func (f *FS) MkdirAll(p string, perm os.FileMode) error { if err != nil { return err } + fmt.Println(">>>TODO fs/hdfs/hdfs.go:73: pp ", p) return os.MkdirAll(p, perm) } @@ -128,26 +132,5 @@ func (f *FS) Walk(p string, wf filepath.WalkFunc) error { } func (f *FS) locate(p string) (string, error) { - pt, err := f.Parse(p) - if err != nil { - return "", err - } - - var info here.Info - if pt.Pkg == "." { - info, err = f.Current() - if err != nil { - return "", err - } - pt.Pkg = info.ImportPath - } - - if info.IsZero() { - info, err = f.Info(pt.Pkg) - if err != nil { - return "", fmt.Errorf("%s: %s", pt, err) - } - } - fp := filepath.Join(info.Dir, pt.Name) - return fp, nil + return f.current.FilePath(p), nil } diff --git a/fs/hdfs/hdfs_test.go b/fs/hdfs/hdfs_test.go deleted file mode 100644 index 6d52926..0000000 --- a/fs/hdfs/hdfs_test.go +++ /dev/null @@ -1,23 +0,0 @@ -package hdfs - -import ( - "log" - - "github.com/markbates/pkger/fs/fstest" -) - -func NewFS() *FS { - fs, err := New() - if err != nil { - log.Fatal(err) - } - return fs -} - -var Folder = fstest.TestFiles{ - "/testdata/hdfs_test/main.go": {Data: []byte("!/testdata/hdfs_test/main.go")}, - "/testdata/hdfs_test/public/index.html": {Data: []byte("!/testdata/hdfs_test/public/index.html")}, - "/testdata/hdfs_test/public/images/mark.png": {Data: []byte("!/testdata/hdfs_test/public/images/mark.png")}, - "/testdata/hdfs_test/templates/a.txt": {Data: []byte("!/testdata/hdfs_test/templates/a.txt")}, - "/testdata/hdfs_test/templates/b/b.txt": {Data: []byte("!/testdata/hdfs_test/templates/b/b.txt")}, -} diff --git a/fs/hdfs/http_test.go b/fs/hdfs/http_test.go deleted file mode 100644 index c97e85f..0000000 --- a/fs/hdfs/http_test.go +++ /dev/null @@ -1,84 +0,0 @@ -package hdfs - -import ( - "io/ioutil" - "net/http" - "net/http/httptest" - "testing" - - "github.com/stretchr/testify/require" -) - -func Test_HTTP_Dir(t *testing.T) { - r := require.New(t) - - fs := NewFS() - - r.NoError(Folder.Create(fs)) - - dir, err := fs.Open("/") - r.NoError(err) - ts := httptest.NewServer(http.FileServer(dir)) - defer ts.Close() - - res, err := http.Get(ts.URL + "/") - r.NoError(err) - r.Equal(200, res.StatusCode) - - b, err := ioutil.ReadAll(res.Body) - r.NoError(err) - r.Contains(string(b), `/public/images/mark.png`) -} - -func Test_HTTP_File_Memory(t *testing.T) { - r := require.New(t) - - fs := NewFS() - r.NoError(Folder.Create(fs)) - - dir, err := fs.Open("/") - r.NoError(err) - ts := httptest.NewServer(http.FileServer(dir)) - defer ts.Close() - - res, err := http.Get(ts.URL + "/public/images/mark.png") - r.NoError(err) - r.Equal(200, res.StatusCode) - - b, err := ioutil.ReadAll(res.Body) - r.NoError(err) - r.Contains(string(b), `!/public/images/mark.png`) -} - -func Test_HTTP_Dir_Memory_StripPrefix(t *testing.T) { - r := require.New(t) - - fs := NewFS() - r.NoError(Folder.Create(fs)) - - dir, err := fs.Open("/public") - r.NoError(err) - defer dir.Close() - - ts := httptest.NewServer(http.StripPrefix("/assets/", http.FileServer(dir))) - defer ts.Close() - - res, err := http.Get(ts.URL + "/assets/images/mark.png") - r.NoError(err) - r.Equal(200, res.StatusCode) - - b, _ := ioutil.ReadAll(res.Body) - // r.NoError(err) - r.Contains(string(b), "!/public/images/mark.png") - - res, err = http.Get(ts.URL + "/assets/images/") - r.NoError(err) - r.Equal(200, res.StatusCode) - - b, _ = ioutil.ReadAll(res.Body) - // r.NoError(err) - r.Contains(string(b), `/mark.png`) - r.NotContains(string(b), `/public`) - r.NotContains(string(b), `/images`) - r.NotContains(string(b), `/go.mod`) -} diff --git a/fs/hdfs/json_test.go b/fs/hdfs/json_test.go deleted file mode 100644 index e569706..0000000 --- a/fs/hdfs/json_test.go +++ /dev/null @@ -1,44 +0,0 @@ -package hdfs - -import ( - "encoding/json" - "io" - "io/ioutil" - "strings" - "testing" - - "github.com/stretchr/testify/require" -) - -func Test_File_JSON(t *testing.T) { - r := require.New(t) - - fs := NewFS() - - f, err := fs.Create("/radio.radio") - r.NoError(err) - _, err = io.Copy(f, strings.NewReader(radio)) - r.NoError(err) - r.NoError(f.Close()) - - f, err = fs.Open("/radio.radio") - r.NoError(err) - bi, err := f.Stat() - r.NoError(err) - - mj, err := json.Marshal(f) - r.NoError(err) - - f2 := &File{} - - r.NoError(json.Unmarshal(mj, f2)) - - ai, err := f2.Stat() - r.NoError(err) - - r.Equal(bi.Size(), ai.Size()) - - fd, err := ioutil.ReadAll(f2) - r.NoError(err) - r.Equal(radio, string(fd)) -} diff --git a/fs/hdfs/mkdirall_test.go b/fs/hdfs/mkdirall_test.go deleted file mode 100644 index 2506dfc..0000000 --- a/fs/hdfs/mkdirall_test.go +++ /dev/null @@ -1,23 +0,0 @@ -package hdfs - -import ( - "os" - "testing" - - "github.com/stretchr/testify/require" -) - -func Test_MkdirAll(t *testing.T) { - r := require.New(t) - - fs := NewFS() - err := fs.MkdirAll("/foo/bar/baz", 0755) - r.NoError(err) - - fi, err := fs.Stat("/foo/bar/baz") - r.NoError(err) - - r.Equal("/foo/bar/baz", fi.Name()) - r.Equal(os.FileMode(0755), fi.Mode()) - r.True(fi.IsDir()) -} diff --git a/fs/hdfs/open_test.go b/fs/hdfs/open_test.go deleted file mode 100644 index 2805825..0000000 --- a/fs/hdfs/open_test.go +++ /dev/null @@ -1,32 +0,0 @@ -package hdfs - -import ( - "io" - "io/ioutil" - "strings" - "testing" - - "github.com/stretchr/testify/require" -) - -func Test_Open(t *testing.T) { - r := require.New(t) - - fs := NewFS() - - _, err := fs.Open("/i.dont.exist") - r.Error(err) - - f, err := fs.Create("/i.exist") - r.NoError(err) - _, err = io.Copy(f, strings.NewReader(radio)) - r.NoError(err) - r.NoError(f.Close()) - - f, err = fs.Open("/i.exist") - r.NoError(err) - b, err := ioutil.ReadAll(f) - r.NoError(err) - r.NoError(f.Close()) - r.Equal([]byte(radio), b) -} diff --git a/fs/hdfs/stat_test.go b/fs/hdfs/stat_test.go deleted file mode 100644 index 3ce3eaf..0000000 --- a/fs/hdfs/stat_test.go +++ /dev/null @@ -1,24 +0,0 @@ -package hdfs - -import ( - "testing" - - "github.com/stretchr/testify/require" -) - -func Test_Stat(t *testing.T) { - r := require.New(t) - - fs := NewFS() - - _, err := fs.Stat("/i.dont.exist") - r.Error(err) - - f, err := fs.Create("/i.exist") - r.NoError(err) - r.NoError(f.Close()) - - fi, err := fs.Stat("/i.exist") - r.NoError(err) - r.Equal("/i.exist", fi.Name()) -} diff --git a/fs/hdfs/walk_test.go b/fs/hdfs/walk_test.go deleted file mode 100644 index 61117e2..0000000 --- a/fs/hdfs/walk_test.go +++ /dev/null @@ -1,67 +0,0 @@ -package hdfs - -import ( - "io" - "os" - "sort" - "strings" - "testing" - - "github.com/stretchr/testify/require" -) - -func Test_Walk(t *testing.T) { - r := require.New(t) - - files := []struct { - name string - body string - }{ - {name: "/a/a.txt", body: "A"}, - {name: "/a/a.md", body: "Amd"}, - {name: "/b/c/d.txt", body: "B"}, - {name: "/f.txt", body: "F"}, - } - - sort.Slice(files, func(a, b int) bool { - return files[a].name < files[b].name - }) - - fs := NewFS() - - for _, file := range files { - f, err := fs.Create(file.name) - r.NoError(err) - _, err = io.Copy(f, strings.NewReader(file.body)) - r.NoError(err) - r.NoError(f.Close()) - } - - var found []string - err := fs.Walk("/", func(path string, info os.FileInfo, err error) error { - if err != nil { - return err - } - - found = append(found, path) - return nil - }) - r.NoError(err) - - expected := []string{":/", ":/a", ":/a/a.md", ":/a/a.txt", ":/b", ":/b/c", ":/b/c/d.txt", ":/f.txt"} - r.Equal(expected, found) - - found = []string{} - err = fs.Walk("/a/", func(path string, info os.FileInfo, err error) error { - if err != nil { - return err - } - - found = append(found, path) - return nil - }) - r.NoError(err) - - expected = []string{":/a/a.md", ":/a/a.txt"} - r.Equal(expected, found) -} diff --git a/testdata/public/radio.radio b/testdata/public/radio.radio deleted file mode 100644 index 0509516..0000000 --- a/testdata/public/radio.radio +++ /dev/null @@ -1,35 +0,0 @@ -I was tuning in the shine on the late night dial -Doing anything my radio advised -With every one of those late night stations -Playing songs bringing tears to my eyes -I was seriously thinking about hiding the receiver -When the switch broke 'cause it's old -They're saying things that I can hardly believe -They really think we're getting out of control -Radio is a sound salvation -Radio is cleaning up the nation -They say you better listen to the voice of reason -But they don't give you any choice 'cause they think that it's treason -So you had better do as you are told -You better listen to the radio -I wanna bite the hand that feeds me -I wanna bite that hand so badly -I want to make them wish they'd never seen me -Some of my friends sit around every evening -And they worry about the times ahead -But everybody else is overwhelmed by indifference -And the promise of an early bed -You either shut up or get cut up; they don't wanna hear about it -It's only inches on the reel-to-reel -And the radio is in the hands of such a lot of fools -Tryin' to anesthetize the way that you feel -Radio is a sound salvation -Radio is cleaning up the nation -They say you better listen to the voice of reason -But they don't give you any choice 'cause they think that it's treason -So you had better do as you are told -You better listen to the radio -Wonderful radio -Marvelous radio -Wonderful radio -Radio, radio \ No newline at end of file From 704b38d3ea484cd71d0918e18428dcc9d324b8d9 Mon Sep 17 00:00:00 2001 From: Mark Bates Date: Sat, 31 Aug 2019 22:45:22 -0400 Subject: [PATCH 04/46] this stolen feeling! --- fs/fs.go | 26 ++++- fs/fstest/file.go | 27 +---- fs/fstest/fstest.go | 45 +++++++ fs/fstest/suite.go | 124 ++++++++++++++++++++ fs/hdfs/hdfs.go | 17 ++- fs/hdfs/hdfs_test.go | 20 ++++ fs/hdfs/hello.txt | 0 fs/hdfs/i.exist | 0 fs/hdfs/radio.radio | 0 fs/memfs/create.go | 2 +- fs/memfs/create_test.go | 166 +++++++++++++------------- fs/memfs/file_test.go | 124 +++++++++----------- fs/memfs/http_test.go | 155 ++++++++++++------------ fs/memfs/json_test.go | 72 +++++------- fs/memfs/memfs.go | 47 ++++++++ fs/memfs/memfs_test.go | 30 +++-- fs/memfs/open_test.go | 54 ++++----- open_test.go | 253 +++++++++++++++++++--------------------- 18 files changed, 672 insertions(+), 490 deletions(-) create mode 100644 fs/fstest/fstest.go create mode 100644 fs/fstest/suite.go create mode 100644 fs/hdfs/hdfs_test.go delete mode 100644 fs/hdfs/hello.txt delete mode 100644 fs/hdfs/i.exist delete mode 100644 fs/hdfs/radio.radio diff --git a/fs/fs.go b/fs/fs.go index 99482a3..5985f04 100644 --- a/fs/fs.go +++ b/fs/fs.go @@ -8,13 +8,31 @@ import ( ) type FileSystem interface { - Create(name string) (File, error) + Parse(p string) (Path, error) Current() (here.Info, error) Info(p string) (here.Info, error) - MkdirAll(p string, perm os.FileMode) error - Open(name string) (File, error) - Parse(p string) (Path, error) + + // ReadFile reads the file named by filename and returns the contents. A successful call returns err == nil, not err == EOF. Because ReadFile reads the whole file, it does not treat an EOF from Read as an error to be reported. ReadFile(s string) ([]byte, error) + + // Create creates the named file with mode 0666 (before umask) - It's actually 0644, truncating it if it already exists. If successful, methods on the returned File can be used for I/O; the associated file descriptor has mode O_RDWR. + Create(name string) (File, error) + + // MkdirAll creates a directory named path, along with any necessary parents, and returns nil, or else returns an error. The permission bits perm (before umask) are used for all directories that MkdirAll creates. If path is already a directory, MkdirAll does nothing and returns nil. + MkdirAll(p string, perm os.FileMode) error + + // Open opens the named file for reading. If successful, methods on the returned file can be used for reading; the associated file descriptor has mode O_RDONLY. + Open(name string) (File, error) + + // Stat returns a FileInfo describing the named file. Stat(name string) (os.FileInfo, error) + + // Walk walks the file tree rooted at root, calling walkFn for each file or directory in the tree, including root. All errors that arise visiting files and directories are filtered by walkFn. The files are walked in lexical order, which makes the output deterministic but means that for very large directories Walk can be inefficient. Walk does not follow symbolic links. - That is from the standard library. I know. Their grammar teachers can not be happy with them right now. Walk(p string, wf filepath.WalkFunc) error + + // Remove removes the named file or (empty) directory. + Remove(name string) error + + // RemoveAll removes path and any children it contains. It removes everything it can but returns the first error it encounters. If the path does not exist, RemoveAll returns nil (no error). + RemoveAll(path string) error } diff --git a/fs/fstest/file.go b/fs/fstest/file.go index cc675df..1ec491a 100644 --- a/fs/fstest/file.go +++ b/fs/fstest/file.go @@ -1,37 +1,12 @@ package fstest import ( - "bytes" - "io" - "github.com/markbates/pkger/fs" ) type TestFile struct { Name string - Data []byte -} - -func (t TestFile) Create(fx fs.FileSystem) error { - f, err := fx.Create(t.Name) - if err != nil { - return err - } - _, err = io.Copy(f, bytes.NewReader(t.Data)) - if err != nil { - return err - } - return f.Close() + Path fs.Path } type TestFiles map[string]TestFile - -func (t TestFiles) Create(fx fs.FileSystem) error { - for k, f := range t { - f.Name = k - if err := f.Create(fx); err != nil { - return err - } - } - return nil -} diff --git a/fs/fstest/fstest.go b/fs/fstest/fstest.go new file mode 100644 index 0000000..25c72d5 --- /dev/null +++ b/fs/fstest/fstest.go @@ -0,0 +1,45 @@ +package fstest + +import ( + "fmt" + "path" + "strings" + + "github.com/markbates/pkger/fs" +) + +func Files(fx fs.FileSystem) (TestFiles, error) { + info, err := fx.Current() + if err != nil { + return nil, err + } + tf := TestFiles{} + for _, f := range fileList { + name := Path(fx, f) + tf[name] = TestFile{ + Name: name, + Path: fs.Path{ + Pkg: info.ImportPath, + Name: name, + }, + } + } + + return tf, nil +} + +func Path(fx fs.FileSystem, ps ...string) string { + name := path.Join("/.fstest", fmt.Sprintf("%T", fx)) + name = path.Join(name, strings.Join(ps, "/")) + return name +} + +var fileList = []string{ + "/main.go", + "/go.mod", + "/go.sum", + "/public/index.html", + "/public/images/mark.png", + "/templates/a.txt", + "/templates/b/b.txt", +} diff --git a/fs/fstest/suite.go b/fs/fstest/suite.go new file mode 100644 index 0000000..21f40c6 --- /dev/null +++ b/fs/fstest/suite.go @@ -0,0 +1,124 @@ +package fstest + +import ( + "fmt" + "os" + "reflect" + "strings" + "testing" + + "github.com/markbates/pkger/fs" + "github.com/stretchr/testify/require" +) + +type FileSystem struct { + FS fs.FileSystem +} + +func NewFileSystem(yourfs fs.FileSystem) (*FileSystem, error) { + suite := &FileSystem{ + FS: yourfs, + } + return suite, nil +} + +func (s *FileSystem) Test(t *testing.T) { + rv := reflect.ValueOf(s) + rt := rv.Type() + if rt.NumMethod() == 0 { + t.Fatalf("something went wrong wrong with %s %T", s, s) + } + for i := 0; i < rt.NumMethod(); i++ { + m := rt.Method(i) + if !strings.HasPrefix(m.Name, "Test_") { + continue + } + s.sub(t, m) + } +} + +func (s *FileSystem) sub(t *testing.T, m reflect.Method) { + name := strings.TrimPrefix(m.Name, "Test_") + name = fmt.Sprintf("%T_%s", s.FS, name) + t.Run(name, func(st *testing.T) { + defer func() { + if err := recover(); err != nil { + st.Fatal(err) + } + }() + + cleaner := func() { + if err := s.Clean(); err != nil { + st.Fatal(err) + } + } + cleaner() + + defer cleaner() + m.Func.Call([]reflect.Value{ + reflect.ValueOf(s), + reflect.ValueOf(st), + }) + }) +} + +func (s *FileSystem) Clean() error { + name := Path(s.FS) + err := s.FS.RemoveAll(name) + if err != nil { + return err + } + + if _, err := s.FS.Stat(name); err == nil { + return fmt.Errorf("expected %q to be, you know, not there any more", name) + } + return nil +} + +func (s *FileSystem) Test_Create(t *testing.T) { + r := require.New(t) + name := Path(s.FS, "i", "want", "candy.song") + + f, err := s.FS.Create(name) + r.NoError(err) + r.Equal(name, f.Name()) + + fi, err := f.Stat() + r.NoError(err) + + r.Equal(name, fi.Name()) + r.Equal(os.FileMode(0644), fi.Mode()) + r.NotZero(fi.ModTime()) +} + +func (s *FileSystem) Test_Current(t *testing.T) { + panic("not implemented") +} + +func (s *FileSystem) Test_Info(t *testing.T) { + panic("not implemented") +} + +func (s *FileSystem) Test_MkdirAll(t *testing.T) { + panic("not implemented") +} + +func (s *FileSystem) Test_Open(t *testing.T) { + panic("not implemented") +} + +func (s *FileSystem) Test_Parse(t *testing.T) { + panic("not implemented") +} + +func (s *FileSystem) Test_ReadFile(t *testing.T) { + panic("not implemented") +} + +func (s *FileSystem) Test_Stat(t *testing.T) { + panic("not implemented") +} + +func (s *FileSystem) Test_Walk(t *testing.T) { + panic("not implemented") +} diff --git a/fs/hdfs/hdfs.go b/fs/hdfs/hdfs.go index 3d4892d..71bd1b6 100644 --- a/fs/hdfs/hdfs.go +++ b/fs/hdfs/hdfs.go @@ -69,7 +69,6 @@ func (f *FS) MkdirAll(p string, perm os.FileMode) error { if err != nil { return err } - fmt.Println(">>>TODO fs/hdfs/hdfs.go:73: pp ", p) return os.MkdirAll(p, perm) } @@ -134,3 +133,19 @@ func (f *FS) Walk(p string, wf filepath.WalkFunc) error { func (f *FS) locate(p string) (string, error) { return f.current.FilePath(p), nil } + +func (fx *FS) Remove(name string) error { + name, err := fx.locate(name) + if err != nil { + return err + } + return os.Remove(name) +} + +func (fx *FS) RemoveAll(name string) error { + name, err := fx.locate(name) + if err != nil { + return err + } + return os.RemoveAll(name) +} diff --git a/fs/hdfs/hdfs_test.go b/fs/hdfs/hdfs_test.go new file mode 100644 index 0000000..2804acc --- /dev/null +++ b/fs/hdfs/hdfs_test.go @@ -0,0 +1,20 @@ +package hdfs + +import ( + "testing" + + "github.com/markbates/pkger/fs/fstest" + "github.com/stretchr/testify/require" +) + +func Test_FS(t *testing.T) { + r := require.New(t) + + myfs, err := New() + r.NoError(err) + + suite, err := fstest.NewFileSystem(myfs) + r.NoError(err) + + suite.Test(t) +} diff --git a/fs/hdfs/hello.txt b/fs/hdfs/hello.txt deleted file mode 100644 index e69de29..0000000 diff --git a/fs/hdfs/i.exist b/fs/hdfs/i.exist deleted file mode 100644 index e69de29..0000000 diff --git a/fs/hdfs/radio.radio b/fs/hdfs/radio.radio deleted file mode 100644 index e69de29..0000000 diff --git a/fs/memfs/create.go b/fs/memfs/create.go index 76bd253..b4eeb09 100644 --- a/fs/memfs/create.go +++ b/fs/memfs/create.go @@ -23,7 +23,7 @@ func (fx *FS) Create(name string) (fs.File, error) { info: &fs.FileInfo{ Details: fs.Details{ Name: pt.Name, - Mode: 0666, + Mode: 0644, ModTime: fs.ModTime(time.Now()), }, }, diff --git a/fs/memfs/create_test.go b/fs/memfs/create_test.go index 411dbca..1761e64 100644 --- a/fs/memfs/create_test.go +++ b/fs/memfs/create_test.go @@ -1,90 +1,80 @@ package memfs -import ( - "io" - "os" - "strings" - "testing" - - "github.com/markbates/pkger/here" - "github.com/stretchr/testify/require" -) - -func Test_Create(t *testing.T) { - r := require.New(t) - - fs, err := New(here.Info{}) - f, err := fs.Create("/hello.txt") - r.NoError(err) - r.NotNil(f) - - fi, err := f.Stat() - r.NoError(err) - - r.Equal("/hello.txt", fi.Name()) - r.Equal(os.FileMode(0666), fi.Mode()) - r.NotZero(fi.ModTime()) -} - -func Test_Create_Write(t *testing.T) { - r := require.New(t) - - fs, err := New(here.Info{}) - f, err := fs.Create("/hello.txt") - r.NoError(err) - r.NotNil(f) - - fi, err := f.Stat() - r.NoError(err) - r.Zero(fi.Size()) - - r.Equal("/hello.txt", fi.Name()) - - mt := fi.ModTime() - r.NotZero(mt) - - sz, err := io.Copy(f, strings.NewReader(radio)) - r.NoError(err) - r.Equal(int64(1381), sz) - - r.NoError(f.Close()) - r.Equal(int64(1381), fi.Size()) - r.NotZero(fi.ModTime()) - r.NotEqual(mt, fi.ModTime()) -} - -const radio = `I was tuning in the shine on the late night dial -Doing anything my radio advised -With every one of those late night stations -Playing songs bringing tears to my eyes -I was seriously thinking about hiding the receiver -When the switch broke 'cause it's old -They're saying things that I can hardly believe -They really think we're getting out of control -Radio is a sound salvation -Radio is cleaning up the nation -They say you better listen to the voice of reason -But they don't give you any choice 'cause they think that it's treason -So you had better do as you are told -You better listen to the radio -I wanna bite the hand that feeds me -I wanna bite that hand so badly -I want to make them wish they'd never seen me -Some of my friends sit around every evening -And they worry about the times ahead -But everybody else is overwhelmed by indifference -And the promise of an early bed -You either shut up or get cut up; they don't wanna hear about it -It's only inches on the reel-to-reel -And the radio is in the hands of such a lot of fools -Tryin' to anesthetize the way that you feel -Radio is a sound salvation -Radio is cleaning up the nation -They say you better listen to the voice of reason -But they don't give you any choice 'cause they think that it's treason -So you had better do as you are told -You better listen to the radio -Wonderful radio -Marvelous radio -Wonderful radio -Radio, radio` +// func Test_Create(t *testing.T) { +// r := require.New(t) +// +// fs, err := New(here.Info{}) +// f, err := fs.Create("/hello.txt") +// r.NoError(err) +// r.NotNil(f) +// +// fi, err := f.Stat() +// r.NoError(err) +// +// r.Equal("/hello.txt", fi.Name()) +// r.Equal(os.FileMode(0666), fi.Mode()) +// r.NotZero(fi.ModTime()) +// } +// +// func Test_Create_Write(t *testing.T) { +// r := require.New(t) +// +// fs, err := New(here.Info{}) +// f, err := fs.Create("/hello.txt") +// r.NoError(err) +// r.NotNil(f) +// +// fi, err := f.Stat() +// r.NoError(err) +// r.Zero(fi.Size()) +// +// r.Equal("/hello.txt", fi.Name()) +// +// mt := fi.ModTime() +// r.NotZero(mt) +// +// sz, err := io.Copy(f, strings.NewReader(radio)) +// r.NoError(err) +// r.Equal(int64(1381), sz) +// +// r.NoError(f.Close()) +// r.Equal(int64(1381), fi.Size()) +// r.NotZero(fi.ModTime()) +// r.NotEqual(mt, fi.ModTime()) +// } +// +// const radio = `I was tuning in the shine on the late night dial +// Doing anything my radio advised +// With every one of those late night stations +// Playing songs bringing tears to my eyes +// I was seriously thinking about hiding the receiver +// When the switch broke 'cause it's old +// They're saying things that I can hardly believe +// They really think we're getting out of control +// Radio is a sound salvation +// Radio is cleaning up the nation +// They say you better listen to the voice of reason +// But they don't give you any choice 'cause they think that it's treason +// So you had better do as you are told +// You better listen to the radio +// I wanna bite the hand that feeds me +// I wanna bite that hand so badly +// I want to make them wish they'd never seen me +// Some of my friends sit around every evening +// And they worry about the times ahead +// But everybody else is overwhelmed by indifference +// And the promise of an early bed +// You either shut up or get cut up; they don't wanna hear about it +// It's only inches on the reel-to-reel +// And the radio is in the hands of such a lot of fools +// Tryin' to anesthetize the way that you feel +// Radio is a sound salvation +// Radio is cleaning up the nation +// They say you better listen to the voice of reason +// But they don't give you any choice 'cause they think that it's treason +// So you had better do as you are told +// You better listen to the radio +// Wonderful radio +// Marvelous radio +// Wonderful radio +// Radio, radio` diff --git a/fs/memfs/file_test.go b/fs/memfs/file_test.go index 73e9552..e2f4231 100644 --- a/fs/memfs/file_test.go +++ b/fs/memfs/file_test.go @@ -1,70 +1,58 @@ package memfs -import ( - "bytes" - "io" - "io/ioutil" - "strings" - "testing" - "time" - - "github.com/markbates/pkger/here" - "github.com/stretchr/testify/require" -) - -func Test_File_Read_Memory(t *testing.T) { - r := require.New(t) - - fs, err := New(here.Info{}) - r.NoError(err) - - f, err := fs.Create("/file_test.go") - r.NoError(err) - _, err = io.Copy(f, bytes.NewReader([]byte("hi!"))) - r.NoError(err) - r.NoError(f.Close()) - - f, err = fs.Open("/file_test.go") - r.NoError(err) - fi, err := f.Stat() - r.NoError(err) - r.Equal("/file_test.go", fi.Name()) - - b, err := ioutil.ReadAll(f) - r.NoError(err) - r.Equal(string(b), "hi!") -} - -func Test_File_Write(t *testing.T) { - r := require.New(t) - - fs, err := New(here.Info{}) - r.NoError(err) - - f, err := fs.Create("/hello.txt") - r.NoError(err) - r.NotNil(f) - - fi, err := f.Stat() - r.NoError(err) - r.Zero(fi.Size()) - - r.Equal("/hello.txt", fi.Name()) - - mt := fi.ModTime() - r.NotZero(mt) - - sz, err := io.Copy(f, strings.NewReader(radio)) - r.NoError(err) - r.Equal(int64(1381), sz) - - // because windows can't handle the time precisely - // enough, we have to *force* just a smidge of time - // to ensure the two ModTime's are different. - // i know, i hate it too. - time.Sleep(time.Millisecond) - r.NoError(f.Close()) - r.Equal(int64(1381), fi.Size()) - r.NotZero(fi.ModTime()) - r.NotEqual(mt, fi.ModTime()) -} +// func Test_File_Read_Memory(t *testing.T) { +// r := require.New(t) +// +// fs, err := New(here.Info{}) +// r.NoError(err) +// +// f, err := fs.Create("/file_test.go") +// r.NoError(err) +// _, err = io.Copy(f, bytes.NewReader([]byte("hi!"))) +// r.NoError(err) +// r.NoError(f.Close()) +// +// f, err = fs.Open("/file_test.go") +// r.NoError(err) +// fi, err := f.Stat() +// r.NoError(err) +// r.Equal("/file_test.go", fi.Name()) +// +// b, err := ioutil.ReadAll(f) +// r.NoError(err) +// r.Equal(string(b), "hi!") +// } +// +// func Test_File_Write(t *testing.T) { +// r := require.New(t) +// +// fs, err := New(here.Info{}) +// r.NoError(err) +// +// f, err := fs.Create("/hello.txt") +// r.NoError(err) +// r.NotNil(f) +// +// fi, err := f.Stat() +// r.NoError(err) +// r.Zero(fi.Size()) +// +// r.Equal("/hello.txt", fi.Name()) +// +// mt := fi.ModTime() +// r.NotZero(mt) +// +// sz, err := io.Copy(f, strings.NewReader(radio)) +// r.NoError(err) +// r.Equal(int64(1381), sz) +// +// // because windows can't handle the time precisely +// // enough, we have to *force* just a smidge of time +// // to ensure the two ModTime's are different. +// // i know, i hate it too. +// time.Sleep(time.Millisecond) +// r.NoError(f.Close()) +// r.Equal(int64(1381), fi.Size()) +// r.NotZero(fi.ModTime()) +// r.NotEqual(mt, fi.ModTime()) +// } diff --git a/fs/memfs/http_test.go b/fs/memfs/http_test.go index 1dbf8b6..ba0f237 100644 --- a/fs/memfs/http_test.go +++ b/fs/memfs/http_test.go @@ -1,84 +1,75 @@ package memfs -import ( - "io/ioutil" - "net/http" - "net/http/httptest" - "testing" - - "github.com/stretchr/testify/require" -) - -func Test_HTTP_Dir(t *testing.T) { - r := require.New(t) - - fs := NewFS() - - r.NoError(Folder.Create(fs)) - - dir, err := fs.Open("/") - r.NoError(err) - ts := httptest.NewServer(http.FileServer(dir)) - defer ts.Close() - - res, err := http.Get(ts.URL + "/") - r.NoError(err) - r.Equal(200, res.StatusCode) - - b, err := ioutil.ReadAll(res.Body) - r.NoError(err) - r.Contains(string(b), `/public/images/mark.png`) -} - -func Test_HTTP_File_Memory(t *testing.T) { - r := require.New(t) - - fs := NewFS() - r.NoError(Folder.Create(fs)) - - dir, err := fs.Open("/") - r.NoError(err) - ts := httptest.NewServer(http.FileServer(dir)) - defer ts.Close() - - res, err := http.Get(ts.URL + "/public/images/mark.png") - r.NoError(err) - r.Equal(200, res.StatusCode) - - b, err := ioutil.ReadAll(res.Body) - r.NoError(err) - r.Contains(string(b), `!/public/images/mark.png`) -} - -func Test_HTTP_Dir_Memory_StripPrefix(t *testing.T) { - r := require.New(t) - - fs := NewFS() - r.NoError(Folder.Create(fs)) - - dir, err := fs.Open("/public") - r.NoError(err) - defer dir.Close() - - ts := httptest.NewServer(http.StripPrefix("/assets/", http.FileServer(dir))) - defer ts.Close() - - res, err := http.Get(ts.URL + "/assets/images/mark.png") - r.NoError(err) - r.Equal(200, res.StatusCode) - - b, _ := ioutil.ReadAll(res.Body) - // r.NoError(err) - r.Contains(string(b), "!/public/images/mark.png") - - res, err = http.Get(ts.URL + "/assets/images/") - r.NoError(err) - r.Equal(200, res.StatusCode) - - b, _ = ioutil.ReadAll(res.Body) - // r.NoError(err) - r.Contains(string(b), `/mark.png`) - r.NotContains(string(b), `/public`) - r.NotContains(string(b), `/images`) - r.NotContains(string(b), `/go.mod`) -} +// func Test_HTTP_Dir(t *testing.T) { +// r := require.New(t) +// +// fs := NewFS() +// +// r.NoError(Folder.Create(fs)) +// +// dir, err := fs.Open("/") +// r.NoError(err) +// ts := httptest.NewServer(http.FileServer(dir)) +// defer ts.Close() +// +// res, err := http.Get(ts.URL + "/") +// r.NoError(err) +// r.Equal(200, res.StatusCode) +// +// b, err := ioutil.ReadAll(res.Body) +// r.NoError(err) +// r.Contains(string(b), `/public/images/mark.png`) +// } +// +// func Test_HTTP_File_Memory(t *testing.T) { +// r := require.New(t) +// +// fs := NewFS() +// r.NoError(Folder.Create(fs)) +// +// dir, err := fs.Open("/") +// r.NoError(err) +// ts := httptest.NewServer(http.FileServer(dir)) +// defer ts.Close() +// +// res, err := http.Get(ts.URL + "/public/images/mark.png") +// r.NoError(err) +// r.Equal(200, res.StatusCode) +// +// b, err := ioutil.ReadAll(res.Body) +// r.NoError(err) +// r.Contains(string(b), `!/public/images/mark.png`) +// } +// +// func Test_HTTP_Dir_Memory_StripPrefix(t *testing.T) { +// r := require.New(t) +// +// fs := NewFS() +// r.NoError(Folder.Create(fs)) +// +// dir, err := fs.Open("/public") +// r.NoError(err) +// defer dir.Close() +// +// ts := httptest.NewServer(http.StripPrefix("/assets/", http.FileServer(dir))) +// defer ts.Close() +// +// res, err := http.Get(ts.URL + "/assets/images/mark.png") +// r.NoError(err) +// r.Equal(200, res.StatusCode) +// +// b, _ := ioutil.ReadAll(res.Body) +// // r.NoError(err) +// r.Contains(string(b), "!/public/images/mark.png") +// +// res, err = http.Get(ts.URL + "/assets/images/") +// r.NoError(err) +// r.Equal(200, res.StatusCode) +// +// b, _ = ioutil.ReadAll(res.Body) +// // r.NoError(err) +// r.Contains(string(b), `/mark.png`) +// r.NotContains(string(b), `/public`) +// r.NotContains(string(b), `/images`) +// r.NotContains(string(b), `/go.mod`) +// } diff --git a/fs/memfs/json_test.go b/fs/memfs/json_test.go index 9ba7487..c257cc2 100644 --- a/fs/memfs/json_test.go +++ b/fs/memfs/json_test.go @@ -1,43 +1,33 @@ package memfs -import ( - "encoding/json" - "io" - "strings" - "testing" - - "github.com/markbates/pkger/here" - "github.com/stretchr/testify/require" -) - -func Test_File_JSON(t *testing.T) { - r := require.New(t) - - fs, err := New(here.Info{}) - r.NoError(err) - - f, err := fs.Create("/radio.radio") - r.NoError(err) - _, err = io.Copy(f, strings.NewReader(radio)) - r.NoError(err) - r.NoError(f.Close()) - - f, err = fs.Open("/radio.radio") - r.NoError(err) - bi, err := f.Stat() - r.NoError(err) - - mj, err := json.Marshal(f) - r.NoError(err) - - f2 := &File{} - - r.NoError(json.Unmarshal(mj, f2)) - - ai, err := f2.Stat() - r.NoError(err) - - r.Equal(bi.Size(), ai.Size()) - - r.Equal(radio, string(f2.data)) -} +// func Test_File_JSON(t *testing.T) { +// r := require.New(t) +// +// fs, err := New(here.Info{}) +// r.NoError(err) +// +// f, err := fs.Create("/radio.radio") +// r.NoError(err) +// _, err = io.Copy(f, strings.NewReader(radio)) +// r.NoError(err) +// r.NoError(f.Close()) +// +// f, err = fs.Open("/radio.radio") +// r.NoError(err) +// bi, err := f.Stat() +// r.NoError(err) +// +// mj, err := json.Marshal(f) +// r.NoError(err) +// +// f2 := &File{} +// +// r.NoError(json.Unmarshal(mj, f2)) +// +// ai, err := f2.Stat() +// r.NoError(err) +// +// r.Equal(bi.Size(), ai.Size()) +// +// r.Equal(radio, string(f2.data)) +// } diff --git a/fs/memfs/memfs.go b/fs/memfs/memfs.go index f88065b..9a6b2a3 100644 --- a/fs/memfs/memfs.go +++ b/fs/memfs/memfs.go @@ -1,7 +1,10 @@ package memfs import ( + "fmt" "io/ioutil" + "os" + "strings" "github.com/markbates/pkger/fs" "github.com/markbates/pkger/here" @@ -56,3 +59,47 @@ func (fx *FS) ReadFile(s string) ([]byte, error) { defer f.Close() return ioutil.ReadAll(f) } + +func (fx *FS) Remove(name string) error { + pt, err := fx.Parse(name) + if err != nil { + return err + } + + if _, ok := fx.files.Load(pt); !ok { + return &os.PathError{"remove", pt.String(), fmt.Errorf("no such file or directory")} + } + + fx.files.Delete(pt) + return nil +} + +func (fx *FS) RemoveAll(name string) error { + pt, err := fx.Parse(name) + if err != nil { + return err + } + + return fx.Walk("/", func(path string, info os.FileInfo, err error) error { + if err != nil { + return err + } + + if !strings.HasPrefix(path, pt.String()) { + return nil + } + + ph, err := fx.Parse(path) + if err != nil { + return err + } + fx.files.Delete(ph) + return nil + }) + if _, ok := fx.files.Load(pt); !ok { + return &os.PathError{"remove", pt.String(), fmt.Errorf("no such file or directory")} + } + + fx.files.Delete(pt) + return nil +} diff --git a/fs/memfs/memfs_test.go b/fs/memfs/memfs_test.go index fbfc5e3..1ae72d1 100644 --- a/fs/memfs/memfs_test.go +++ b/fs/memfs/memfs_test.go @@ -1,26 +1,24 @@ package memfs import ( - "log" + "testing" "github.com/markbates/pkger/fs/fstest" "github.com/markbates/pkger/here" + "github.com/stretchr/testify/require" ) -func NewFS() *FS { - fs, err := New(here.Info{}) - if err != nil { - log.Fatal(err) - } - return fs -} +func Test_FS(t *testing.T) { + r := require.New(t) -var Folder = fstest.TestFiles{ - "/main.go": {Data: []byte("!/main.go")}, - "/go.mod": {Data: []byte("!/go.mod")}, - "/go.sum": {Data: []byte("!/go.sum")}, - "/public/index.html": {Data: []byte("!/public/index.html")}, - "/public/images/mark.png": {Data: []byte("!/public/images/mark.png")}, - "/templates/a.txt": {Data: []byte("!/templates/a.txt")}, - "/templates/b/b.txt": {Data: []byte("!/templates/b/b.txt")}, + info, err := here.Current() + r.NoError(err) + + myfs, err := New(info) + r.NoError(err) + + suite, err := fstest.NewFileSystem(myfs) + r.NoError(err) + + suite.Test(t) } diff --git a/fs/memfs/open_test.go b/fs/memfs/open_test.go index b173b08..4442bd5 100644 --- a/fs/memfs/open_test.go +++ b/fs/memfs/open_test.go @@ -1,34 +1,24 @@ package memfs -import ( - "io" - "io/ioutil" - "strings" - "testing" - - "github.com/markbates/pkger/here" - "github.com/stretchr/testify/require" -) - -func Test_Open(t *testing.T) { - r := require.New(t) - - fs, err := New(here.Info{}) - r.NoError(err) - - _, err = fs.Open("/i.dont.exist") - r.Error(err) - - f, err := fs.Create("/i.exist") - r.NoError(err) - _, err = io.Copy(f, strings.NewReader(radio)) - r.NoError(err) - r.NoError(f.Close()) - - f, err = fs.Open("/i.exist") - r.NoError(err) - b, err := ioutil.ReadAll(f) - r.NoError(err) - r.NoError(f.Close()) - r.Equal([]byte(radio), b) -} +// func Test_Open(t *testing.T) { +// r := require.New(t) +// +// fs, err := New(here.Info{}) +// r.NoError(err) +// +// _, err = fs.Open("/i.dont.exist") +// r.Error(err) +// +// f, err := fs.Create("/i.exist") +// r.NoError(err) +// _, err = io.Copy(f, strings.NewReader(radio)) +// r.NoError(err) +// r.NoError(f.Close()) +// +// f, err = fs.Open("/i.exist") +// r.NoError(err) +// b, err := ioutil.ReadAll(f) +// r.NoError(err) +// r.NoError(f.Close()) +// r.Equal([]byte(radio), b) +// } diff --git a/open_test.go b/open_test.go index 5e0811f..82545f2 100644 --- a/open_test.go +++ b/open_test.go @@ -1,133 +1,124 @@ package pkger -import ( - "io/ioutil" - "net/http" - "net/http/httptest" - "testing" - - "github.com/stretchr/testify/require" -) - -func Test_Open_File(t *testing.T) { - r := require.New(t) - - f, err := Open(".") - r.NoError(err) - - ts := httptest.NewServer(http.FileServer(f)) - defer ts.Close() - - res, err := http.Get(ts.URL + "/cmd/pkger/main.go") - r.NoError(err) - r.Equal(200, res.StatusCode) - - b, err := ioutil.ReadAll(res.Body) - r.NoError(err) - r.Contains(string(b), "does not compute") - - r.NoError(f.Close()) -} - -func Test_Open_Dir(t *testing.T) { - r := require.New(t) - - f, err := Open("/") - r.NoError(err) - - ts := httptest.NewServer(http.FileServer(f)) - defer ts.Close() - - res, err := http.Get(ts.URL + "/cmd/pkger") - r.NoError(err) - r.Equal(200, res.StatusCode) - - b, err := ioutil.ReadAll(res.Body) - r.NoError(err) - r.Contains(string(b), `/cmd/pkger/main.go`) - - r.NoError(f.Close()) -} - -func Test_Open_File_Memory(t *testing.T) { - r := require.New(t) - - f, err := Create("/suit/case.txt") - r.NoError(err) - f.Write([]byte(radio)) - r.NoError(f.Close()) - - r.Equal([]byte(radio), f.data) - r.Contains(string(f.data), "I wanna bite the hand that feeds me") - - dir, err := Open("/") - r.NoError(err) - defer dir.Close() - - ts := httptest.NewServer(http.FileServer(dir)) - defer ts.Close() - - res, err := http.Get(ts.URL + "/suit/case.txt") - r.NoError(err) - r.Equal(200, res.StatusCode) - - b, _ := ioutil.ReadAll(res.Body) - // r.NoError(err) - r.Contains(string(b), "I wanna bite the hand that feeds me") - -} - -func Test_Open_Dir_StripPrefix(t *testing.T) { - r := require.New(t) - - ts := httptest.NewServer(http.StripPrefix("/assets/", http.FileServer(http.Dir("./testdata/public")))) - defer ts.Close() - - res, err := http.Get(ts.URL + "/assets/radio.radio") - r.NoError(err) - r.Equal(200, res.StatusCode) - - b, _ := ioutil.ReadAll(res.Body) - // r.NoError(err) - r.Contains(string(b), "I wanna bite the hand that feeds me") - - res, err = http.Get(ts.URL + "/assets/") - r.NoError(err) - r.Equal(200, res.StatusCode) - - b, _ = ioutil.ReadAll(res.Body) - // r.NoError(err) - r.Contains(string(b), `radio.radio`) -} - -func Test_Open_Dir_Memory_StripPrefix(t *testing.T) { - r := require.New(t) - - err := MkdirAll("/testdata/public", 0755) - r.NoError(err) - - dir, err := Open("/testdata/public") - r.NoError(err) - defer dir.Close() - - ts := httptest.NewServer(http.StripPrefix("/assets/", http.FileServer(dir))) - defer ts.Close() - - res, err := http.Get(ts.URL + "/assets/radio.radio") - r.NoError(err) - r.Equal(200, res.StatusCode) - - b, _ := ioutil.ReadAll(res.Body) - // r.NoError(err) - r.Contains(string(b), "I wanna bite the hand that feeds me") - - res, err = http.Get(ts.URL + "/assets/") - r.NoError(err) - r.Equal(200, res.StatusCode) - - b, _ = ioutil.ReadAll(res.Body) - // r.NoError(err) - r.Contains(string(b), `/radio.radio`) - r.NotContains(string(b), `/public`) - r.NotContains(string(b), `//`) -} +// func Test_Open_File(t *testing.T) { +// r := require.New(t) +// +// f, err := Open(".") +// r.NoError(err) +// +// ts := httptest.NewServer(http.FileServer(f)) +// defer ts.Close() +// +// res, err := http.Get(ts.URL + "/cmd/pkger/main.go") +// r.NoError(err) +// r.Equal(200, res.StatusCode) +// +// b, err := ioutil.ReadAll(res.Body) +// r.NoError(err) +// r.Contains(string(b), "does not compute") +// +// r.NoError(f.Close()) +// } +// +// func Test_Open_Dir(t *testing.T) { +// r := require.New(t) +// +// f, err := Open("/") +// r.NoError(err) +// +// ts := httptest.NewServer(http.FileServer(f)) +// defer ts.Close() +// +// res, err := http.Get(ts.URL + "/cmd/pkger") +// r.NoError(err) +// r.Equal(200, res.StatusCode) +// +// b, err := ioutil.ReadAll(res.Body) +// r.NoError(err) +// r.Contains(string(b), `/cmd/pkger/main.go`) +// +// r.NoError(f.Close()) +// } +// +// func Test_Open_File_Memory(t *testing.T) { +// r := require.New(t) +// +// f, err := Create("/suit/case.txt") +// r.NoError(err) +// f.Write([]byte(radio)) +// r.NoError(f.Close()) +// +// r.Equal([]byte(radio), f.data) +// r.Contains(string(f.data), "I wanna bite the hand that feeds me") +// +// dir, err := Open("/") +// r.NoError(err) +// defer dir.Close() +// +// ts := httptest.NewServer(http.FileServer(dir)) +// defer ts.Close() +// +// res, err := http.Get(ts.URL + "/suit/case.txt") +// r.NoError(err) +// r.Equal(200, res.StatusCode) +// +// b, _ := ioutil.ReadAll(res.Body) +// // r.NoError(err) +// r.Contains(string(b), "I wanna bite the hand that feeds me") +// +// } +// +// func Test_Open_Dir_StripPrefix(t *testing.T) { +// r := require.New(t) +// +// ts := httptest.NewServer(http.StripPrefix("/assets/", http.FileServer(http.Dir("./testdata/public")))) +// defer ts.Close() +// +// res, err := http.Get(ts.URL + "/assets/radio.radio") +// r.NoError(err) +// r.Equal(200, res.StatusCode) +// +// b, _ := ioutil.ReadAll(res.Body) +// // r.NoError(err) +// r.Contains(string(b), "I wanna bite the hand that feeds me") +// +// res, err = http.Get(ts.URL + "/assets/") +// r.NoError(err) +// r.Equal(200, res.StatusCode) +// +// b, _ = ioutil.ReadAll(res.Body) +// // r.NoError(err) +// r.Contains(string(b), `radio.radio`) +// } +// +// func Test_Open_Dir_Memory_StripPrefix(t *testing.T) { +// r := require.New(t) +// +// err := MkdirAll("/testdata/public", 0755) +// r.NoError(err) +// +// dir, err := Open("/testdata/public") +// r.NoError(err) +// defer dir.Close() +// +// ts := httptest.NewServer(http.StripPrefix("/assets/", http.FileServer(dir))) +// defer ts.Close() +// +// res, err := http.Get(ts.URL + "/assets/radio.radio") +// r.NoError(err) +// r.Equal(200, res.StatusCode) +// +// b, _ := ioutil.ReadAll(res.Body) +// // r.NoError(err) +// r.Contains(string(b), "I wanna bite the hand that feeds me") +// +// res, err = http.Get(ts.URL + "/assets/") +// r.NoError(err) +// r.Equal(200, res.StatusCode) +// +// b, _ = ioutil.ReadAll(res.Body) +// // r.NoError(err) +// r.Contains(string(b), `/radio.radio`) +// r.NotContains(string(b), `/public`) +// r.NotContains(string(b), `//`) +// } From ffdb70686a893a403ecb62aec24ffbc07016307d Mon Sep 17 00:00:00 2001 From: Mark Bates Date: Sat, 31 Aug 2019 22:47:23 -0400 Subject: [PATCH 05/46] green eyes --- fs/fstest/suite.go | 6 +++++- fs/memfs/memfs.go | 7 ++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/fs/fstest/suite.go b/fs/fstest/suite.go index 21f40c6..a7a6fa8 100644 --- a/fs/fstest/suite.go +++ b/fs/fstest/suite.go @@ -92,7 +92,11 @@ func (s *FileSystem) Test_Create(t *testing.T) { } func (s *FileSystem) Test_Current(t *testing.T) { - panic("not implemented") + r := require.New(t) + + info, err := s.FS.Current() + r.NoError(err) + r.NotZero(info) } func (s *FileSystem) Test_Info(t *testing.T) { diff --git a/fs/memfs/memfs.go b/fs/memfs/memfs.go index 9a6b2a3..87ab709 100644 --- a/fs/memfs/memfs.go +++ b/fs/memfs/memfs.go @@ -15,9 +15,10 @@ var _ fs.FileSystem = &FS{} func New(info here.Info) (*FS, error) { f := &FS{ - infos: &maps.Infos{}, - paths: &maps.Paths{}, - files: &maps.Files{}, + infos: &maps.Infos{}, + paths: &maps.Paths{}, + files: &maps.Files{}, + current: info, } return f, nil } From 915694eb9de0999edd9558e7c4f68220205528f6 Mon Sep 17 00:00:00 2001 From: Mark Bates Date: Sat, 31 Aug 2019 23:29:25 -0400 Subject: [PATCH 06/46] my hands are tied --- fs/fstest/file.go | 2 +- fs/fstest/fstest.go | 31 +++++------ fs/fstest/suite.go | 39 ++++++++----- fs/hdfs/hdfs.go | 17 +++--- fs/memfs/memfs.go | 21 ++++--- fs/memfs/memfs_test.go | 3 + fs/memfs/stat_test.go | 39 ++++++------- fs/memfs/walk_test.go | 123 +++++++++++++++++++---------------------- 8 files changed, 139 insertions(+), 136 deletions(-) diff --git a/fs/fstest/file.go b/fs/fstest/file.go index 1ec491a..7c61646 100644 --- a/fs/fstest/file.go +++ b/fs/fstest/file.go @@ -9,4 +9,4 @@ type TestFile struct { Path fs.Path } -type TestFiles map[string]TestFile +type TestFiles map[fs.Path]TestFile diff --git a/fs/fstest/fstest.go b/fs/fstest/fstest.go index 25c72d5..d2d5856 100644 --- a/fs/fstest/fstest.go +++ b/fs/fstest/fstest.go @@ -1,7 +1,6 @@ package fstest import ( - "fmt" "path" "strings" @@ -9,29 +8,29 @@ import ( ) func Files(fx fs.FileSystem) (TestFiles, error) { - info, err := fx.Current() - if err != nil { - return nil, err - } tf := TestFiles{} for _, f := range fileList { - name := Path(fx, f) - tf[name] = TestFile{ - Name: name, - Path: fs.Path{ - Pkg: info.ImportPath, - Name: name, - }, + pt, err := Path(fx, f) + if err != nil { + return tf, err + } + tf[pt] = TestFile{ + Name: pt.Name, + Path: pt, } } return tf, nil } -func Path(fx fs.FileSystem, ps ...string) string { - name := path.Join("/.fstest", fmt.Sprintf("%T", fx)) - name = path.Join(name, strings.Join(ps, "/")) - return name +func Path(fx fs.FileSystem, ps ...string) (fs.Path, error) { + name := path.Join(ps...) + name = path.Join(".fstest", name) + if !strings.HasPrefix(name, "/") { + name = "/" + name + } + + return fx.Parse(name) } var fileList = []string{ diff --git a/fs/fstest/suite.go b/fs/fstest/suite.go index a7a6fa8..8071c67 100644 --- a/fs/fstest/suite.go +++ b/fs/fstest/suite.go @@ -12,12 +12,12 @@ import ( ) type FileSystem struct { - FS fs.FileSystem + fs.FileSystem } func NewFileSystem(yourfs fs.FileSystem) (*FileSystem, error) { suite := &FileSystem{ - FS: yourfs, + FileSystem: yourfs, } return suite, nil } @@ -39,7 +39,7 @@ func (s *FileSystem) Test(t *testing.T) { func (s *FileSystem) sub(t *testing.T, m reflect.Method) { name := strings.TrimPrefix(m.Name, "Test_") - name = fmt.Sprintf("%T_%s", s.FS, name) + name = fmt.Sprintf("%T_%s", s.FileSystem, name) t.Run(name, func(st *testing.T) { defer func() { if err := recover(); err != nil { @@ -63,30 +63,35 @@ func (s *FileSystem) sub(t *testing.T, m reflect.Method) { } func (s *FileSystem) Clean() error { - name := Path(s.FS) - err := s.FS.RemoveAll(name) + pt, err := Path(s) if err != nil { return err } - if _, err := s.FS.Stat(name); err == nil { - return fmt.Errorf("expected %q to be, you know, not there any more", name) + if err := s.RemoveAll(pt.Name); err != nil { + return err + } + + if _, err := s.Stat(pt.Name); err == nil { + return fmt.Errorf("expected %q to be, you know, not there any more", pt) } return nil } func (s *FileSystem) Test_Create(t *testing.T) { r := require.New(t) - name := Path(s.FS, "i", "want", "candy.song") - f, err := s.FS.Create(name) + pt, err := Path(s, "i", "want", "candy.song") r.NoError(err) - r.Equal(name, f.Name()) + + f, err := s.Create(pt.Name) + r.NoError(err) + r.Equal(pt.Name, f.Name()) fi, err := f.Stat() r.NoError(err) - r.Equal(name, fi.Name()) + r.Equal(pt.Name, fi.Name()) r.Equal(os.FileMode(0644), fi.Mode()) r.NotZero(fi.ModTime()) } @@ -94,13 +99,21 @@ func (s *FileSystem) Test_Create(t *testing.T) { func (s *FileSystem) Test_Current(t *testing.T) { r := require.New(t) - info, err := s.FS.Current() + info, err := s.Current() r.NoError(err) r.NotZero(info) } func (s *FileSystem) Test_Info(t *testing.T) { - panic("not implemented") + r := require.New(t) + + cur, err := s.Current() + r.NoError(err) + + info, err := s.Info(cur.ImportPath) + r.NoError(err) + r.NotZero(info) + } func (s *FileSystem) Test_MkdirAll(t *testing.T) { diff --git a/fs/hdfs/hdfs.go b/fs/hdfs/hdfs.go index 71bd1b6..1beaa01 100644 --- a/fs/hdfs/hdfs.go +++ b/fs/hdfs/hdfs.go @@ -21,14 +21,17 @@ type FS struct { } func New() (*FS, error) { - f := &FS{ - infos: &maps.Infos{}, - paths: &maps.Paths{}, + info, err := here.Current() + if err != nil { + return nil, err } - - var err error - f.current, err = here.Current() - return f, err + return &FS{ + infos: &maps.Infos{}, + paths: &maps.Paths{ + Current: info, + }, + current: info, + }, nil } func (fx *FS) Create(name string) (fs.File, error) { diff --git a/fs/memfs/memfs.go b/fs/memfs/memfs.go index 87ab709..e254141 100644 --- a/fs/memfs/memfs.go +++ b/fs/memfs/memfs.go @@ -13,10 +13,18 @@ import ( var _ fs.FileSystem = &FS{} +func WithInfo(fx *FS, infos ...here.Info) { + for _, info := range infos { + fx.infos.Store(info.ImportPath, info) + } +} + func New(info here.Info) (*FS, error) { f := &FS{ - infos: &maps.Infos{}, - paths: &maps.Paths{}, + infos: &maps.Infos{}, + paths: &maps.Paths{ + Current: info, + }, files: &maps.Files{}, current: info, } @@ -36,15 +44,10 @@ func (f *FS) Current() (here.Info, error) { func (f *FS) Info(p string) (here.Info, error) { info, ok := f.infos.Load(p) - if ok { - return info, nil + if !ok { + return info, fmt.Errorf("no such package %q", p) } - info, err := here.Package(p) - if err != nil { - return info, err - } - f.infos.Store(p, info) return info, nil } diff --git a/fs/memfs/memfs_test.go b/fs/memfs/memfs_test.go index 1ae72d1..9afa490 100644 --- a/fs/memfs/memfs_test.go +++ b/fs/memfs/memfs_test.go @@ -13,10 +13,13 @@ func Test_FS(t *testing.T) { info, err := here.Current() r.NoError(err) + r.NotZero(info) myfs, err := New(info) r.NoError(err) + WithInfo(myfs, info) + suite, err := fstest.NewFileSystem(myfs) r.NoError(err) diff --git a/fs/memfs/stat_test.go b/fs/memfs/stat_test.go index d6aa990..492c41c 100644 --- a/fs/memfs/stat_test.go +++ b/fs/memfs/stat_test.go @@ -1,25 +1,18 @@ package memfs -import ( - "testing" - - "github.com/markbates/pkger/here" - "github.com/stretchr/testify/require" -) - -func Test_Stat(t *testing.T) { - r := require.New(t) - - fs, err := New(here.Info{}) - r.NoError(err) - _, err = fs.Stat("/i.dont.exist") - r.Error(err) - - f, err := fs.Create("/i.exist") - r.NoError(err) - r.NoError(f.Close()) - - fi, err := fs.Stat("/i.exist") - r.NoError(err) - r.Equal("/i.exist", fi.Name()) -} +// func Test_Stat(t *testing.T) { +// r := require.New(t) +// +// fs, err := New(here.Info{}) +// r.NoError(err) +// _, err = fs.Stat("/i.dont.exist") +// r.Error(err) +// +// f, err := fs.Create("/i.exist") +// r.NoError(err) +// r.NoError(f.Close()) +// +// fi, err := fs.Stat("/i.exist") +// r.NoError(err) +// r.Equal("/i.exist", fi.Name()) +// } diff --git a/fs/memfs/walk_test.go b/fs/memfs/walk_test.go index aa56657..179368a 100644 --- a/fs/memfs/walk_test.go +++ b/fs/memfs/walk_test.go @@ -1,69 +1,58 @@ package memfs -import ( - "io" - "os" - "sort" - "strings" - "testing" - - "github.com/markbates/pkger/here" - "github.com/stretchr/testify/require" -) - -func Test_Walk(t *testing.T) { - r := require.New(t) - - files := []struct { - name string - body string - }{ - {name: "/a/a.txt", body: "A"}, - {name: "/a/a.md", body: "Amd"}, - {name: "/b/c/d.txt", body: "B"}, - {name: "/f.txt", body: "F"}, - } - - sort.Slice(files, func(a, b int) bool { - return files[a].name < files[b].name - }) - - fs, err := New(here.Info{}) - r.NoError(err) - - for _, file := range files { - f, err := fs.Create(file.name) - r.NoError(err) - _, err = io.Copy(f, strings.NewReader(file.body)) - r.NoError(err) - r.NoError(f.Close()) - } - - var found []string - err = fs.Walk("/", func(path string, info os.FileInfo, err error) error { - if err != nil { - return err - } - - found = append(found, path) - return nil - }) - r.NoError(err) - - expected := []string{":/", ":/a", ":/a/a.md", ":/a/a.txt", ":/b", ":/b/c", ":/b/c/d.txt", ":/f.txt"} - r.Equal(expected, found) - - found = []string{} - err = fs.Walk("/a/", func(path string, info os.FileInfo, err error) error { - if err != nil { - return err - } - - found = append(found, path) - return nil - }) - r.NoError(err) - - expected = []string{":/a/a.md", ":/a/a.txt"} - r.Equal(expected, found) -} +// func Test_Walk(t *testing.T) { +// r := require.New(t) +// +// files := []struct { +// name string +// body string +// }{ +// {name: "/a/a.txt", body: "A"}, +// {name: "/a/a.md", body: "Amd"}, +// {name: "/b/c/d.txt", body: "B"}, +// {name: "/f.txt", body: "F"}, +// } +// +// sort.Slice(files, func(a, b int) bool { +// return files[a].name < files[b].name +// }) +// +// fs, err := New(here.Info{}) +// r.NoError(err) +// +// for _, file := range files { +// f, err := fs.Create(file.name) +// r.NoError(err) +// _, err = io.Copy(f, strings.NewReader(file.body)) +// r.NoError(err) +// r.NoError(f.Close()) +// } +// +// var found []string +// err = fs.Walk("/", func(path string, info os.FileInfo, err error) error { +// if err != nil { +// return err +// } +// +// found = append(found, path) +// return nil +// }) +// r.NoError(err) +// +// expected := []string{":/", ":/a", ":/a/a.md", ":/a/a.txt", ":/b", ":/b/c", ":/b/c/d.txt", ":/f.txt"} +// r.Equal(expected, found) +// +// found = []string{} +// err = fs.Walk("/a/", func(path string, info os.FileInfo, err error) error { +// if err != nil { +// return err +// } +// +// found = append(found, path) +// return nil +// }) +// r.NoError(err) +// +// expected = []string{":/a/a.md", ":/a/a.txt"} +// r.Equal(expected, found) +// } From f05a546d9e9b07d9afb48f1e838dbfa3b9b45644 Mon Sep 17 00:00:00 2001 From: Mark Bates Date: Sun, 1 Sep 2019 00:03:01 -0400 Subject: [PATCH 07/46] envying the irony that is rock and roll --- fs/fstest/suite.go | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/fs/fstest/suite.go b/fs/fstest/suite.go index 8071c67..3680248 100644 --- a/fs/fstest/suite.go +++ b/fs/fstest/suite.go @@ -125,7 +125,31 @@ func (s *FileSystem) Test_Open(t *testing.T) { } func (s *FileSystem) Test_Parse(t *testing.T) { - panic("not implemented") + r := require.New(t) + + cur, err := s.Current() + r.NoError(err) + + ip := cur.ImportPath + table := []struct { + in string + exp fs.Path + }{ + {in: "/foo.go", exp: fs.Path{Pkg: ip, Name: "/foo.go"}}, + {in: ":/foo.go", exp: fs.Path{Pkg: ip, Name: "/foo.go"}}, + {in: ip + ":/foo.go", exp: fs.Path{Pkg: ip, Name: "/foo.go"}}, + {in: ip, exp: fs.Path{Pkg: ip, Name: "/"}}, + } + + for _, tt := range table { + t.Run(tt.in, func(st *testing.T) { + r := require.New(st) + + pt, err := s.Parse(tt.in) + r.NoError(err) + r.Equal(tt.exp, pt) + }) + } } func (s *FileSystem) Test_ReadFile(t *testing.T) { From 9666017c2c0c9da081840aeb25f0bcb99a7dc14e Mon Sep 17 00:00:00 2001 From: Mark Bates Date: Sun, 1 Sep 2019 13:21:34 -0400 Subject: [PATCH 08/46] champagne illinois --- fs/fstest/fstest.go | 14 +++++------ fs/fstest/suite.go | 53 +++++++++++++++++++++++++++++++++++++++--- fs/memfs/stat.go | 2 +- internal/maps/paths.go | 6 +++-- 4 files changed, 61 insertions(+), 14 deletions(-) diff --git a/fs/fstest/fstest.go b/fs/fstest/fstest.go index d2d5856..342d371 100644 --- a/fs/fstest/fstest.go +++ b/fs/fstest/fstest.go @@ -2,7 +2,6 @@ package fstest import ( "path" - "strings" "github.com/markbates/pkger/fs" ) @@ -23,14 +22,13 @@ func Files(fx fs.FileSystem) (TestFiles, error) { return tf, nil } -func Path(fx fs.FileSystem, ps ...string) (fs.Path, error) { - name := path.Join(ps...) - name = path.Join(".fstest", name) - if !strings.HasPrefix(name, "/") { - name = "/" + name +func Path(fx fs.FileSystem, p string) (fs.Path, error) { + pt, err := fx.Parse(p) + if err != nil { + return pt, err } - - return fx.Parse(name) + pt.Name = path.Join("/.fstest", pt.Name) + return pt, nil } var fileList = []string{ diff --git a/fs/fstest/suite.go b/fs/fstest/suite.go index 3680248..d243048 100644 --- a/fs/fstest/suite.go +++ b/fs/fstest/suite.go @@ -63,7 +63,7 @@ func (s *FileSystem) sub(t *testing.T, m reflect.Method) { } func (s *FileSystem) Clean() error { - pt, err := Path(s) + pt, err := Path(s, "/") if err != nil { return err } @@ -81,7 +81,7 @@ func (s *FileSystem) Clean() error { func (s *FileSystem) Test_Create(t *testing.T) { r := require.New(t) - pt, err := Path(s, "i", "want", "candy.song") + pt, err := Path(s, "i/want/candy.song") r.NoError(err) f, err := s.Create(pt.Name) @@ -139,6 +139,10 @@ func (s *FileSystem) Test_Parse(t *testing.T) { {in: ":/foo.go", exp: fs.Path{Pkg: ip, Name: "/foo.go"}}, {in: ip + ":/foo.go", exp: fs.Path{Pkg: ip, Name: "/foo.go"}}, {in: ip, exp: fs.Path{Pkg: ip, Name: "/"}}, + {in: ":", exp: fs.Path{Pkg: ip, Name: "/"}}, + {in: "github.com/old/97s:/foo.go", exp: fs.Path{Pkg: "github.com/old/97s", Name: "/foo.go"}}, + {in: "github.com/old/97s", exp: fs.Path{Pkg: "github.com/old/97s", Name: "/"}}, + {in: "github.com/old/97s:", exp: fs.Path{Pkg: "github.com/old/97s", Name: "/"}}, } for _, tt := range table { @@ -157,7 +161,50 @@ func (s *FileSystem) Test_ReadFile(t *testing.T) { } func (s *FileSystem) Test_Stat(t *testing.T) { - panic("not implemented") + r := require.New(t) + + cur, err := s.Current() + r.NoError(err) + + ip := cur.ImportPath + table := []struct { + in string + err bool + }{ + {in: "/foo.go", err: false}, + {in: ":/foo.go", err: false}, + {in: ip + ":/foo.go", err: false}, + {in: ip, err: false}, + {in: "/no.go", err: true}, + } + + for _, tt := range table { + t.Run(tt.in, func(st *testing.T) { + r := require.New(st) + + if tt.err { + _, err := s.Stat(tt.in) + r.Error(err) + return + } + + pt, err := Path(s, tt.in) + fmt.Println(">>>TODO fs/fstest/suite.go:189: tt.in ", tt.in) + fmt.Println(">>>TODO fs/fstest/suite.go:189: pt ", pt) + r.NoError(err) + + // r.Fail(pt.String()) + // f, err := s.Create(tt.in) + // r.NoError(err) + // _, err = io.Copy(f, strings.NewReader("!"+pt.String())) + // r.NoError(err) + // r.NoError(f.Close()) + + info, err := s.Stat(tt.in) + r.NoError(err) + r.Equal(pt.Name, info.Name()) + }) + } } func (s *FileSystem) Test_Walk(t *testing.T) { diff --git a/fs/memfs/stat.go b/fs/memfs/stat.go index 67f702f..0e9fc6f 100644 --- a/fs/memfs/stat.go +++ b/fs/memfs/stat.go @@ -14,5 +14,5 @@ func (fx *FS) Stat(name string) (os.FileInfo, error) { if ok { return f.Stat() } - return nil, fmt.Errorf("could not stat %s", name) + return nil, fmt.Errorf("could not stat %s", pt) } diff --git a/internal/maps/paths.go b/internal/maps/paths.go index 356bec9..9f64b50 100644 --- a/internal/maps/paths.go +++ b/internal/maps/paths.go @@ -130,12 +130,14 @@ func (m *Paths) Keys() []string { func (m *Paths) Parse(p string) (fs.Path, error) { p = strings.Replace(p, "\\", "/", -1) + p = strings.TrimSpace(p) + pt, ok := m.Load(p) if ok { return pt, nil } - if len(p) == 0 { - return m.build(p, "", "") + if len(p) == 0 || p == ":" { + return m.build("", "", "") } res := pathrx.FindAllStringSubmatch(p, -1) From 926eafe520031c4723fb8d8bb6c128df636353ab Mon Sep 17 00:00:00 2001 From: Mark Bates Date: Sun, 1 Sep 2019 15:42:22 -0400 Subject: [PATCH 09/46] blame it on ray --- .gitignore | 1 + fs/fstest/fstest.go | 13 +------------ fs/fstest/suite.go | 26 ++++++++++++++------------ fs/hdfs/hdfs.go | 7 ++++++- internal/maps/paths.go | 1 + 5 files changed, 23 insertions(+), 25 deletions(-) diff --git a/.gitignore b/.gitignore index 9115a58..6f31e5c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +.fstest *.log .DS_Store doc diff --git a/fs/fstest/fstest.go b/fs/fstest/fstest.go index 342d371..1898958 100644 --- a/fs/fstest/fstest.go +++ b/fs/fstest/fstest.go @@ -1,15 +1,13 @@ package fstest import ( - "path" - "github.com/markbates/pkger/fs" ) func Files(fx fs.FileSystem) (TestFiles, error) { tf := TestFiles{} for _, f := range fileList { - pt, err := Path(fx, f) + pt, err := fx.Parse(f) if err != nil { return tf, err } @@ -22,15 +20,6 @@ func Files(fx fs.FileSystem) (TestFiles, error) { return tf, nil } -func Path(fx fs.FileSystem, p string) (fs.Path, error) { - pt, err := fx.Parse(p) - if err != nil { - return pt, err - } - pt.Name = path.Join("/.fstest", pt.Name) - return pt, nil -} - var fileList = []string{ "/main.go", "/go.mod", diff --git a/fs/fstest/suite.go b/fs/fstest/suite.go index d243048..071cfbc 100644 --- a/fs/fstest/suite.go +++ b/fs/fstest/suite.go @@ -3,6 +3,7 @@ package fstest import ( "fmt" "os" + "path/filepath" "reflect" "strings" "testing" @@ -63,25 +64,26 @@ func (s *FileSystem) sub(t *testing.T, m reflect.Method) { } func (s *FileSystem) Clean() error { - pt, err := Path(s, "/") + pt, err := s.Parse("/") if err != nil { return err } - if err := s.RemoveAll(pt.Name); err != nil { - return err - } - - if _, err := s.Stat(pt.Name); err == nil { - return fmt.Errorf("expected %q to be, you know, not there any more", pt) - } + _ = pt + // if err := s.RemoveAll(pt.Name); err != nil { + // return err + // } + // + // if _, err := s.Stat(pt.Name); err == nil { + // return fmt.Errorf("expected %q to be, you know, not there any more", pt) + // } return nil } func (s *FileSystem) Test_Create(t *testing.T) { r := require.New(t) - pt, err := Path(s, "i/want/candy.song") + pt, err := s.Parse("/i/want/candy.song") r.NoError(err) f, err := s.Create(pt.Name) @@ -94,6 +96,7 @@ func (s *FileSystem) Test_Create(t *testing.T) { r.Equal(pt.Name, fi.Name()) r.Equal(os.FileMode(0644), fi.Mode()) r.NotZero(fi.ModTime()) + r.NoError(s.RemoveAll(pt.String())) } func (s *FileSystem) Test_Current(t *testing.T) { @@ -136,6 +139,7 @@ func (s *FileSystem) Test_Parse(t *testing.T) { exp fs.Path }{ {in: "/foo.go", exp: fs.Path{Pkg: ip, Name: "/foo.go"}}, + {in: filepath.Join(cur.Dir, "foo.go"), exp: fs.Path{Pkg: ip, Name: "/foo.go"}}, {in: ":/foo.go", exp: fs.Path{Pkg: ip, Name: "/foo.go"}}, {in: ip + ":/foo.go", exp: fs.Path{Pkg: ip, Name: "/foo.go"}}, {in: ip, exp: fs.Path{Pkg: ip, Name: "/"}}, @@ -188,9 +192,7 @@ func (s *FileSystem) Test_Stat(t *testing.T) { return } - pt, err := Path(s, tt.in) - fmt.Println(">>>TODO fs/fstest/suite.go:189: tt.in ", tt.in) - fmt.Println(">>>TODO fs/fstest/suite.go:189: pt ", pt) + pt, err := s.Parse(tt.in) r.NoError(err) // r.Fail(pt.String()) diff --git a/fs/hdfs/hdfs.go b/fs/hdfs/hdfs.go index 1beaa01..e9c41f4 100644 --- a/fs/hdfs/hdfs.go +++ b/fs/hdfs/hdfs.go @@ -134,7 +134,12 @@ func (f *FS) Walk(p string, wf filepath.WalkFunc) error { } func (f *FS) locate(p string) (string, error) { - return f.current.FilePath(p), nil + pt, err := f.Parse(p) + if err != nil { + return p, err + } + p = f.current.FilePath(pt.Name) + return p, nil } func (fx *FS) Remove(name string) error { diff --git a/internal/maps/paths.go b/internal/maps/paths.go index 9f64b50..aee61f8 100644 --- a/internal/maps/paths.go +++ b/internal/maps/paths.go @@ -179,6 +179,7 @@ func (m *Paths) build(p, pkg, name string) (fs.Path, error) { if !strings.HasPrefix(pt.Name, "/") { pt.Name = "/" + pt.Name } + pt.Name = strings.TrimPrefix(pt.Name, m.Current.Dir) m.Store(p, pt) return pt, nil } From f1cffaa166723920c5542c93752ca61803cee96e Mon Sep 17 00:00:00 2001 From: Mark Bates Date: Sun, 1 Sep 2019 15:59:42 -0400 Subject: [PATCH 10/46] interstate love song --- fs/fstest/suite.go | 19 ++++++++++--------- fs/hdfs/hdfs_test.go | 4 ++++ 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/fs/fstest/suite.go b/fs/fstest/suite.go index 071cfbc..e6c09f7 100644 --- a/fs/fstest/suite.go +++ b/fs/fstest/suite.go @@ -2,6 +2,7 @@ package fstest import ( "fmt" + "io" "os" "path/filepath" "reflect" @@ -70,9 +71,9 @@ func (s *FileSystem) Clean() error { } _ = pt - // if err := s.RemoveAll(pt.Name); err != nil { - // return err - // } + if err := s.RemoveAll(pt.Name); err != nil { + return err + } // // if _, err := s.Stat(pt.Name); err == nil { // return fmt.Errorf("expected %q to be, you know, not there any more", pt) @@ -195,12 +196,12 @@ func (s *FileSystem) Test_Stat(t *testing.T) { pt, err := s.Parse(tt.in) r.NoError(err) - // r.Fail(pt.String()) - // f, err := s.Create(tt.in) - // r.NoError(err) - // _, err = io.Copy(f, strings.NewReader("!"+pt.String())) - // r.NoError(err) - // r.NoError(f.Close()) + r.Fail(pt.String()) + f, err := s.Create(tt.in) + r.NoError(err) + _, err = io.Copy(f, strings.NewReader("!"+pt.String())) + r.NoError(err) + r.NoError(f.Close()) info, err := s.Stat(tt.in) r.NoError(err) diff --git a/fs/hdfs/hdfs_test.go b/fs/hdfs/hdfs_test.go index 2804acc..4d95a20 100644 --- a/fs/hdfs/hdfs_test.go +++ b/fs/hdfs/hdfs_test.go @@ -1,6 +1,7 @@ package hdfs import ( + "path/filepath" "testing" "github.com/markbates/pkger/fs/fstest" @@ -13,6 +14,9 @@ func Test_FS(t *testing.T) { myfs, err := New() r.NoError(err) + myfs.current.Dir = filepath.Join(myfs.current.Dir, ".fstest") + myfs.paths.Current = myfs.current + suite, err := fstest.NewFileSystem(myfs) r.NoError(err) From 5e24d43bb022ed8cd904e7f085c4aeb61f61eeee Mon Sep 17 00:00:00 2001 From: Mark Bates Date: Sun, 1 Sep 2019 16:00:18 -0400 Subject: [PATCH 11/46] hands are tied --- fs/fstest/suite.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/fs/fstest/suite.go b/fs/fstest/suite.go index e6c09f7..ddeef75 100644 --- a/fs/fstest/suite.go +++ b/fs/fstest/suite.go @@ -74,10 +74,10 @@ func (s *FileSystem) Clean() error { if err := s.RemoveAll(pt.Name); err != nil { return err } - // - // if _, err := s.Stat(pt.Name); err == nil { - // return fmt.Errorf("expected %q to be, you know, not there any more", pt) - // } + + if _, err := s.Stat(pt.Name); err == nil { + return fmt.Errorf("expected %q to be, you know, not there any more", pt) + } return nil } From 6463dbba07e3f336a556c9b6870fc3f32462ba84 Mon Sep 17 00:00:00 2001 From: Mark Bates Date: Sun, 1 Sep 2019 16:18:39 -0400 Subject: [PATCH 12/46] guarded by monkeys --- fs/file.go | 2 +- fs/fs.go | 3 +++ fs/fstest/suite.go | 1 - fs/hdfs/file.go | 47 +++++++++++++++++++++++----------------------- fs/hdfs/hdfs.go | 44 ++++++++++++++++++++++++++----------------- fs/memfs/file.go | 4 ++-- fs/memfs/memfs.go | 12 ++++++++++++ 7 files changed, 69 insertions(+), 44 deletions(-) diff --git a/fs/file.go b/fs/file.go index d558b7b..428c51f 100644 --- a/fs/file.go +++ b/fs/file.go @@ -9,7 +9,7 @@ import ( type File interface { Close() error - FilePath() string + Abs() (string, error) Info() here.Info Name() string Open(name string) (http.File, error) diff --git a/fs/fs.go b/fs/fs.go index 5985f04..c881d78 100644 --- a/fs/fs.go +++ b/fs/fs.go @@ -9,6 +9,9 @@ import ( type FileSystem interface { Parse(p string) (Path, error) + Abs(string) (string, error) + AbsPath(Path) (string, error) + Current() (here.Info, error) Info(p string) (here.Info, error) diff --git a/fs/fstest/suite.go b/fs/fstest/suite.go index ddeef75..e1a5793 100644 --- a/fs/fstest/suite.go +++ b/fs/fstest/suite.go @@ -196,7 +196,6 @@ func (s *FileSystem) Test_Stat(t *testing.T) { pt, err := s.Parse(tt.in) r.NoError(err) - r.Fail(pt.String()) f, err := s.Create(tt.in) r.NoError(err) _, err = io.Copy(f, strings.NewReader("!"+pt.String())) diff --git a/fs/hdfs/file.go b/fs/hdfs/file.go index f2b366c..82f455e 100644 --- a/fs/hdfs/file.go +++ b/fs/hdfs/file.go @@ -3,7 +3,6 @@ package hdfs import ( "net/http" "os" - "strings" "github.com/markbates/pkger/fs" "github.com/markbates/pkger/here" @@ -13,22 +12,18 @@ var _ fs.File = &File{} type File struct { *os.File - filePath string - info *fs.FileInfo - her here.Info - path fs.Path - fs fs.FileSystem + info *fs.FileInfo + her here.Info + path fs.Path + fs fs.FileSystem } func NewFile(fx fs.FileSystem, osf *os.File) (*File, error) { - cur, err := fx.Current() + pt, err := fx.Parse(osf.Name()) if err != nil { return nil, err } - pt := fs.Path{ - Name: strings.TrimPrefix(osf.Name(), cur.Dir), - } info, err := osf.Stat() if err != nil { @@ -36,10 +31,9 @@ func NewFile(fx fs.FileSystem, osf *os.File) (*File, error) { } f := &File{ - File: osf, - filePath: info.Name(), - path: pt, - fs: fx, + File: osf, + path: pt, + fs: fx, } f.info = fs.WithName(pt.Name, info) @@ -55,8 +49,8 @@ func (f *File) Close() error { return f.File.Close() } -func (f *File) FilePath() string { - return f.filePath +func (f *File) Abs() (string, error) { + return f.fs.AbsPath(f.path) } func (f *File) Info() here.Info { @@ -76,12 +70,19 @@ func (f *File) Path() fs.Path { } func (f *File) Stat() (os.FileInfo, error) { - if f.info == nil { - info, err := os.Stat(f.filePath) - if err != nil { - return nil, err - } - f.info = fs.NewFileInfo(info) + if f.info != nil { + return f.info, nil } - return f.info, nil + + abs, err := f.Abs() + if err != nil { + return nil, err + } + + info, err := os.Stat(abs) + if err != nil { + return nil, err + } + f.info = fs.NewFileInfo(info) + return info, nil } diff --git a/fs/hdfs/hdfs.go b/fs/hdfs/hdfs.go index e9c41f4..1bcc889 100644 --- a/fs/hdfs/hdfs.go +++ b/fs/hdfs/hdfs.go @@ -20,6 +20,25 @@ type FS struct { current here.Info } +func (f *FS) Abs(p string) (string, error) { + pt, err := f.Parse(p) + if err != nil { + return "", err + } + return f.AbsPath(pt) +} + +func (f *FS) AbsPath(pt fs.Path) (string, error) { + if pt.Pkg == f.current.ImportPath { + return filepath.Join(f.current.Dir, pt.Name), nil + } + info, err := f.Info(pt.Pkg) + if err != nil { + return "", err + } + return filepath.Join(info.Dir, pt.Name), nil +} + func New() (*FS, error) { info, err := here.Current() if err != nil { @@ -35,7 +54,7 @@ func New() (*FS, error) { } func (fx *FS) Create(name string) (fs.File, error) { - name, err := fx.locate(name) + name, err := fx.Abs(name) if err != nil { return nil, err } @@ -68,7 +87,7 @@ func (f *FS) Info(p string) (here.Info, error) { } func (f *FS) MkdirAll(p string, perm os.FileMode) error { - p, err := f.locate(p) + p, err := f.Abs(p) if err != nil { return err } @@ -76,7 +95,7 @@ func (f *FS) MkdirAll(p string, perm os.FileMode) error { } func (fx *FS) Open(name string) (fs.File, error) { - name, err := fx.locate(name) + name, err := fx.Abs(name) if err != nil { return nil, err } @@ -92,7 +111,7 @@ func (f *FS) Parse(p string) (fs.Path, error) { } func (f *FS) ReadFile(s string) ([]byte, error) { - s, err := f.locate(s) + s, err := f.Abs(s) if err != nil { return nil, err } @@ -100,7 +119,7 @@ func (f *FS) ReadFile(s string) ([]byte, error) { } func (f *FS) Stat(name string) (os.FileInfo, error) { - name, err := f.locate(name) + name, err := f.Abs(name) if err != nil { return nil, err } @@ -108,7 +127,7 @@ func (f *FS) Stat(name string) (os.FileInfo, error) { } func (f *FS) Walk(p string, wf filepath.WalkFunc) error { - fp, err := f.locate(p) + fp, err := f.Abs(p) if err != nil { return err } @@ -133,17 +152,8 @@ func (f *FS) Walk(p string, wf filepath.WalkFunc) error { return err } -func (f *FS) locate(p string) (string, error) { - pt, err := f.Parse(p) - if err != nil { - return p, err - } - p = f.current.FilePath(pt.Name) - return p, nil -} - func (fx *FS) Remove(name string) error { - name, err := fx.locate(name) + name, err := fx.Abs(name) if err != nil { return err } @@ -151,7 +161,7 @@ func (fx *FS) Remove(name string) error { } func (fx *FS) RemoveAll(name string) error { - name, err := fx.locate(name) + name, err := fx.Abs(name) if err != nil { return err } diff --git a/fs/memfs/file.go b/fs/memfs/file.go index 612c12b..0ff8834 100644 --- a/fs/memfs/file.go +++ b/fs/memfs/file.go @@ -98,8 +98,8 @@ func (f File) Name() string { return f.info.Name() } -func (f File) FilePath() string { - return f.her.FilePath(f.Name()) +func (f File) Abs() (string, error) { + return f.fs.AbsPath(f.Path()) } func (f File) Path() fs.Path { diff --git a/fs/memfs/memfs.go b/fs/memfs/memfs.go index e254141..7abb9a5 100644 --- a/fs/memfs/memfs.go +++ b/fs/memfs/memfs.go @@ -38,6 +38,18 @@ type FS struct { current here.Info } +func (f *FS) Abs(p string) (string, error) { + pt, err := f.Parse(p) + if err != nil { + return "", err + } + return f.AbsPath(pt) +} + +func (f *FS) AbsPath(pt fs.Path) (string, error) { + return pt.String(), nil +} + func (f *FS) Current() (here.Info, error) { return f.current, nil } From 7381a1124f63b19b0fe30f3f02603a6dcfe629ed Mon Sep 17 00:00:00 2001 From: Mark Bates Date: Sun, 1 Sep 2019 16:27:31 -0400 Subject: [PATCH 13/46] took the greyhound --- fs/fstest/suite.go | 17 +++++++++++++++-- fs/hdfs/hdfs.go | 17 +++++++++++++++-- 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/fs/fstest/suite.go b/fs/fstest/suite.go index e1a5793..b405ecb 100644 --- a/fs/fstest/suite.go +++ b/fs/fstest/suite.go @@ -185,16 +185,29 @@ func (s *FileSystem) Test_Stat(t *testing.T) { for _, tt := range table { t.Run(tt.in, func(st *testing.T) { + r := require.New(st) + pt, err := s.Parse(tt.in) + r.NoError(err) + + r.NoError(s.RemoveAll(pt.String())) + if tt.err { _, err := s.Stat(tt.in) r.Error(err) return } - pt, err := s.Parse(tt.in) - r.NoError(err) + isDir := filepath.Ext(pt.Name) == "" + + if isDir { + r.NoError(s.MkdirAll(pt.Name, 0755)) + info, err := s.Stat(tt.in) + r.NoError(err) + r.Equal(pt.Name, info.Name()) + return + } f, err := s.Create(tt.in) r.NoError(err) diff --git a/fs/hdfs/hdfs.go b/fs/hdfs/hdfs.go index 1bcc889..fc92489 100644 --- a/fs/hdfs/hdfs.go +++ b/fs/hdfs/hdfs.go @@ -119,11 +119,24 @@ func (f *FS) ReadFile(s string) ([]byte, error) { } func (f *FS) Stat(name string) (os.FileInfo, error) { - name, err := f.Abs(name) + pt, err := f.Parse(name) if err != nil { return nil, err } - return os.Stat(name) + + abs, err := f.AbsPath(pt) + if err != nil { + return nil, err + } + + info, err := os.Stat(abs) + if err != nil { + return nil, err + } + + info = fs.WithName(pt.Name, fs.NewFileInfo(info)) + + return info, nil } func (f *FS) Walk(p string, wf filepath.WalkFunc) error { From fb05947cac6267d4e4eac46e9025ce7901c9a1dc Mon Sep 17 00:00:00 2001 From: Mark Bates Date: Sun, 1 Sep 2019 17:35:38 -0400 Subject: [PATCH 14/46] mouldy --- fs/fstest/suite.go | 114 +++++++++++++++++++++++++++++++++------------ 1 file changed, 85 insertions(+), 29 deletions(-) diff --git a/fs/fstest/suite.go b/fs/fstest/suite.go index b405ecb..ec05239 100644 --- a/fs/fstest/suite.go +++ b/fs/fstest/suite.go @@ -13,6 +13,10 @@ import ( "github.com/stretchr/testify/require" ) +const mould = "/easy/listening/sugar.file" +const hart = "/easy/listening/grant.hart" +const husker = "github.com/husker/du" + type FileSystem struct { fs.FileSystem } @@ -84,7 +88,7 @@ func (s *FileSystem) Clean() error { func (s *FileSystem) Test_Create(t *testing.T) { r := require.New(t) - pt, err := s.Parse("/i/want/candy.song") + pt, err := s.Parse(mould) r.NoError(err) f, err := s.Create(pt.Name) @@ -139,15 +143,15 @@ func (s *FileSystem) Test_Parse(t *testing.T) { in string exp fs.Path }{ - {in: "/foo.go", exp: fs.Path{Pkg: ip, Name: "/foo.go"}}, - {in: filepath.Join(cur.Dir, "foo.go"), exp: fs.Path{Pkg: ip, Name: "/foo.go"}}, - {in: ":/foo.go", exp: fs.Path{Pkg: ip, Name: "/foo.go"}}, - {in: ip + ":/foo.go", exp: fs.Path{Pkg: ip, Name: "/foo.go"}}, + {in: mould, exp: fs.Path{Pkg: ip, Name: mould}}, + {in: filepath.Join(cur.Dir, mould), exp: fs.Path{Pkg: ip, Name: mould}}, + {in: ":" + mould, exp: fs.Path{Pkg: ip, Name: mould}}, + {in: ip + ":" + mould, exp: fs.Path{Pkg: ip, Name: mould}}, {in: ip, exp: fs.Path{Pkg: ip, Name: "/"}}, {in: ":", exp: fs.Path{Pkg: ip, Name: "/"}}, - {in: "github.com/old/97s:/foo.go", exp: fs.Path{Pkg: "github.com/old/97s", Name: "/foo.go"}}, - {in: "github.com/old/97s", exp: fs.Path{Pkg: "github.com/old/97s", Name: "/"}}, - {in: "github.com/old/97s:", exp: fs.Path{Pkg: "github.com/old/97s", Name: "/"}}, + {in: husker + ":" + mould, exp: fs.Path{Pkg: husker, Name: mould}}, + {in: husker, exp: fs.Path{Pkg: husker, Name: "/"}}, + {in: husker + ":", exp: fs.Path{Pkg: husker, Name: "/"}}, } for _, tt := range table { @@ -165,22 +169,22 @@ func (s *FileSystem) Test_ReadFile(t *testing.T) { panic("not implemented") } -func (s *FileSystem) Test_Stat(t *testing.T) { +func (s *FileSystem) Test_Stat_Error(t *testing.T) { r := require.New(t) cur, err := s.Current() r.NoError(err) ip := cur.ImportPath + table := []struct { - in string - err bool + in string }{ - {in: "/foo.go", err: false}, - {in: ":/foo.go", err: false}, - {in: ip + ":/foo.go", err: false}, - {in: ip, err: false}, - {in: "/no.go", err: true}, + {in: hart}, + {in: ":" + hart}, + {in: ip}, + {in: ip + ":"}, + {in: ip + ":" + hart}, } for _, tt := range table { @@ -193,21 +197,73 @@ func (s *FileSystem) Test_Stat(t *testing.T) { r.NoError(s.RemoveAll(pt.String())) - if tt.err { - _, err := s.Stat(tt.in) - r.Error(err) - return - } + _, err = s.Stat(tt.in) + r.Error(err) + }) + } +} - isDir := filepath.Ext(pt.Name) == "" +func (s *FileSystem) Test_Stat_Dir(t *testing.T) { + r := require.New(t) - if isDir { - r.NoError(s.MkdirAll(pt.Name, 0755)) - info, err := s.Stat(tt.in) - r.NoError(err) - r.Equal(pt.Name, info.Name()) - return - } + cur, err := s.Current() + r.NoError(err) + + dir := filepath.Dir(mould) + ip := cur.ImportPath + + table := []struct { + in string + }{ + {in: ip}, + {in: dir}, + {in: ":" + dir}, + {in: ip + ":" + dir}, + } + + for _, tt := range table { + t.Run(tt.in, func(st *testing.T) { + + r := require.New(st) + + pt, err := s.Parse(tt.in) + r.NoError(err) + + r.NoError(s.RemoveAll(pt.String())) + + r.NoError(s.MkdirAll(pt.Name, 0755)) + info, err := s.Stat(tt.in) + r.NoError(err) + r.Equal(pt.Name, info.Name()) + }) + } +} + +func (s *FileSystem) Test_Stat_File(t *testing.T) { + r := require.New(t) + + cur, err := s.Current() + r.NoError(err) + + ip := cur.ImportPath + table := []struct { + in string + }{ + {in: mould}, + {in: ":" + mould}, + {in: ip + ":" + mould}, + {in: hart}, + } + + for _, tt := range table { + t.Run(tt.in, func(st *testing.T) { + + r := require.New(st) + + pt, err := s.Parse(tt.in) + r.NoError(err) + + r.NoError(s.RemoveAll(pt.String())) f, err := s.Create(tt.in) r.NoError(err) From 7779fbd3a9bb4a346fb7250f977b0afe038628b7 Mon Sep 17 00:00:00 2001 From: Mark Bates Date: Sun, 1 Sep 2019 17:41:03 -0400 Subject: [PATCH 15/46] in the pantry with your cupcakes --- fs/fstest/suite.go | 34 +++++++++++++++++----------------- fs/hdfs/hdfs_test.go | 2 +- fs/memfs/memfs_test.go | 2 +- 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/fs/fstest/suite.go b/fs/fstest/suite.go index ec05239..fe04ab9 100644 --- a/fs/fstest/suite.go +++ b/fs/fstest/suite.go @@ -17,18 +17,18 @@ const mould = "/easy/listening/sugar.file" const hart = "/easy/listening/grant.hart" const husker = "github.com/husker/du" -type FileSystem struct { +type Suite struct { fs.FileSystem } -func NewFileSystem(yourfs fs.FileSystem) (*FileSystem, error) { - suite := &FileSystem{ +func NewSuite(yourfs fs.FileSystem) (Suite, error) { + suite := Suite{ FileSystem: yourfs, } return suite, nil } -func (s *FileSystem) Test(t *testing.T) { +func (s Suite) Test(t *testing.T) { rv := reflect.ValueOf(s) rt := rv.Type() if rt.NumMethod() == 0 { @@ -43,7 +43,7 @@ func (s *FileSystem) Test(t *testing.T) { } } -func (s *FileSystem) sub(t *testing.T, m reflect.Method) { +func (s Suite) sub(t *testing.T, m reflect.Method) { name := strings.TrimPrefix(m.Name, "Test_") name = fmt.Sprintf("%T_%s", s.FileSystem, name) t.Run(name, func(st *testing.T) { @@ -68,7 +68,7 @@ func (s *FileSystem) sub(t *testing.T, m reflect.Method) { }) } -func (s *FileSystem) Clean() error { +func (s Suite) Clean() error { pt, err := s.Parse("/") if err != nil { return err @@ -85,7 +85,7 @@ func (s *FileSystem) Clean() error { return nil } -func (s *FileSystem) Test_Create(t *testing.T) { +func (s Suite) Test_Create(t *testing.T) { r := require.New(t) pt, err := s.Parse(mould) @@ -104,7 +104,7 @@ func (s *FileSystem) Test_Create(t *testing.T) { r.NoError(s.RemoveAll(pt.String())) } -func (s *FileSystem) Test_Current(t *testing.T) { +func (s Suite) Test_Current(t *testing.T) { r := require.New(t) info, err := s.Current() @@ -112,7 +112,7 @@ func (s *FileSystem) Test_Current(t *testing.T) { r.NotZero(info) } -func (s *FileSystem) Test_Info(t *testing.T) { +func (s Suite) Test_Info(t *testing.T) { r := require.New(t) cur, err := s.Current() @@ -124,15 +124,15 @@ func (s *FileSystem) Test_Info(t *testing.T) { } -func (s *FileSystem) Test_MkdirAll(t *testing.T) { +func (s Suite) Test_MkdirAll(t *testing.T) { panic("not implemented") } -func (s *FileSystem) Test_Open(t *testing.T) { +func (s Suite) Test_Open(t *testing.T) { panic("not implemented") } -func (s *FileSystem) Test_Parse(t *testing.T) { +func (s Suite) Test_Parse(t *testing.T) { r := require.New(t) cur, err := s.Current() @@ -165,11 +165,11 @@ func (s *FileSystem) Test_Parse(t *testing.T) { } } -func (s *FileSystem) Test_ReadFile(t *testing.T) { +func (s Suite) Test_ReadFile(t *testing.T) { panic("not implemented") } -func (s *FileSystem) Test_Stat_Error(t *testing.T) { +func (s Suite) Test_Stat_Error(t *testing.T) { r := require.New(t) cur, err := s.Current() @@ -203,7 +203,7 @@ func (s *FileSystem) Test_Stat_Error(t *testing.T) { } } -func (s *FileSystem) Test_Stat_Dir(t *testing.T) { +func (s Suite) Test_Stat_Dir(t *testing.T) { r := require.New(t) cur, err := s.Current() @@ -239,7 +239,7 @@ func (s *FileSystem) Test_Stat_Dir(t *testing.T) { } } -func (s *FileSystem) Test_Stat_File(t *testing.T) { +func (s Suite) Test_Stat_File(t *testing.T) { r := require.New(t) cur, err := s.Current() @@ -278,6 +278,6 @@ func (s *FileSystem) Test_Stat_File(t *testing.T) { } } -func (s *FileSystem) Test_Walk(t *testing.T) { +func (s Suite) Test_Walk(t *testing.T) { panic("not implemented") } diff --git a/fs/hdfs/hdfs_test.go b/fs/hdfs/hdfs_test.go index 4d95a20..eeb958e 100644 --- a/fs/hdfs/hdfs_test.go +++ b/fs/hdfs/hdfs_test.go @@ -17,7 +17,7 @@ func Test_FS(t *testing.T) { myfs.current.Dir = filepath.Join(myfs.current.Dir, ".fstest") myfs.paths.Current = myfs.current - suite, err := fstest.NewFileSystem(myfs) + suite, err := fstest.NewSuite(myfs) r.NoError(err) suite.Test(t) diff --git a/fs/memfs/memfs_test.go b/fs/memfs/memfs_test.go index 9afa490..cd27931 100644 --- a/fs/memfs/memfs_test.go +++ b/fs/memfs/memfs_test.go @@ -20,7 +20,7 @@ func Test_FS(t *testing.T) { WithInfo(myfs, info) - suite, err := fstest.NewFileSystem(myfs) + suite, err := fstest.NewSuite(myfs) r.NoError(err) suite.Test(t) From 85055a4cb781c927153b2ad8a8567b120f231d21 Mon Sep 17 00:00:00 2001 From: Mark Bates Date: Sun, 1 Sep 2019 17:47:10 -0400 Subject: [PATCH 16/46] three marlenas --- fs/fs.go | 2 +- fs/fstest/fstest.go | 2 +- fs/fstest/suite.go | 8 ++++---- fs/hdfs/file.go | 4 ++-- fs/hdfs/hdfs.go | 2 +- fs/memfs/file.go | 2 +- fs/memfs/memfs.go | 2 +- 7 files changed, 11 insertions(+), 11 deletions(-) diff --git a/fs/fs.go b/fs/fs.go index c881d78..596b8d7 100644 --- a/fs/fs.go +++ b/fs/fs.go @@ -7,7 +7,7 @@ import ( "github.com/markbates/pkger/here" ) -type FileSystem interface { +type Warehouse interface { Parse(p string) (Path, error) Abs(string) (string, error) AbsPath(Path) (string, error) diff --git a/fs/fstest/fstest.go b/fs/fstest/fstest.go index 1898958..581f6b1 100644 --- a/fs/fstest/fstest.go +++ b/fs/fstest/fstest.go @@ -4,7 +4,7 @@ import ( "github.com/markbates/pkger/fs" ) -func Files(fx fs.FileSystem) (TestFiles, error) { +func Files(fx fs.Warehouse) (TestFiles, error) { tf := TestFiles{} for _, f := range fileList { pt, err := fx.Parse(f) diff --git a/fs/fstest/suite.go b/fs/fstest/suite.go index fe04ab9..5d64d95 100644 --- a/fs/fstest/suite.go +++ b/fs/fstest/suite.go @@ -18,12 +18,12 @@ const hart = "/easy/listening/grant.hart" const husker = "github.com/husker/du" type Suite struct { - fs.FileSystem + fs.Warehouse } -func NewSuite(yourfs fs.FileSystem) (Suite, error) { +func NewSuite(yourfs fs.Warehouse) (Suite, error) { suite := Suite{ - FileSystem: yourfs, + Warehouse: yourfs, } return suite, nil } @@ -45,7 +45,7 @@ func (s Suite) Test(t *testing.T) { func (s Suite) sub(t *testing.T, m reflect.Method) { name := strings.TrimPrefix(m.Name, "Test_") - name = fmt.Sprintf("%T_%s", s.FileSystem, name) + name = fmt.Sprintf("%T_%s", s.Warehouse, name) t.Run(name, func(st *testing.T) { defer func() { if err := recover(); err != nil { diff --git a/fs/hdfs/file.go b/fs/hdfs/file.go index 82f455e..52219f2 100644 --- a/fs/hdfs/file.go +++ b/fs/hdfs/file.go @@ -15,10 +15,10 @@ type File struct { info *fs.FileInfo her here.Info path fs.Path - fs fs.FileSystem + fs fs.Warehouse } -func NewFile(fx fs.FileSystem, osf *os.File) (*File, error) { +func NewFile(fx fs.Warehouse, osf *os.File) (*File, error) { pt, err := fx.Parse(osf.Name()) if err != nil { diff --git a/fs/hdfs/hdfs.go b/fs/hdfs/hdfs.go index fc92489..e80e61f 100644 --- a/fs/hdfs/hdfs.go +++ b/fs/hdfs/hdfs.go @@ -12,7 +12,7 @@ import ( "github.com/markbates/pkger/internal/maps" ) -var _ fs.FileSystem = &FS{} +var _ fs.Warehouse = &FS{} type FS struct { infos *maps.Infos diff --git a/fs/memfs/file.go b/fs/memfs/file.go index 0ff8834..c6192ff 100644 --- a/fs/memfs/file.go +++ b/fs/memfs/file.go @@ -27,7 +27,7 @@ type File struct { parent fs.Path writer *bytes.Buffer reader io.Reader - fs fs.FileSystem + fs fs.Warehouse } func (f *File) Seek(offset int64, whence int) (int64, error) { diff --git a/fs/memfs/memfs.go b/fs/memfs/memfs.go index 7abb9a5..537cf82 100644 --- a/fs/memfs/memfs.go +++ b/fs/memfs/memfs.go @@ -11,7 +11,7 @@ import ( "github.com/markbates/pkger/internal/maps" ) -var _ fs.FileSystem = &FS{} +var _ fs.Warehouse = &FS{} func WithInfo(fx *FS, infos ...here.Info) { for _, info := range infos { From 11770e0d51a6783322b7b1c186a2d4fb29bffd62 Mon Sep 17 00:00:00 2001 From: Mark Bates Date: Sun, 1 Sep 2019 17:50:21 -0400 Subject: [PATCH 17/46] and i feel it slowing down --- fs/info.go | 18 ------------------ fs/memfs/http.go | 1 - fs/{memfs => memwh}/create.go | 2 +- fs/{memfs => memwh}/create_test.go | 2 +- fs/{memfs => memwh}/file.go | 2 +- fs/{memfs => memwh}/file_test.go | 2 +- fs/memwh/http.go | 1 + fs/{memfs => memwh}/http_test.go | 2 +- fs/{memfs => memwh}/json.go | 2 +- fs/{memfs => memwh}/json_test.go | 2 +- fs/{memfs => memwh}/memfs.go | 2 +- fs/{memfs => memwh}/memfs_test.go | 2 +- fs/{memfs => memwh}/mkdirall.go | 2 +- fs/{memfs => memwh}/mkdirall_test.go | 2 +- fs/{memfs => memwh}/open.go | 2 +- fs/{memfs => memwh}/open_test.go | 2 +- fs/{memfs => memwh}/stat.go | 2 +- fs/{memfs => memwh}/stat_test.go | 2 +- fs/{memfs => memwh}/walk.go | 2 +- fs/{memfs => memwh}/walk_test.go | 2 +- fs/mod_time.go | 24 ++++++++++++++++++++++++ fs/{fs.go => warehouse.go} | 0 22 files changed, 42 insertions(+), 36 deletions(-) delete mode 100644 fs/memfs/http.go rename fs/{memfs => memwh}/create.go (97%) rename fs/{memfs => memwh}/create_test.go (99%) rename fs/{memfs => memwh}/file.go (99%) rename fs/{memfs => memwh}/file_test.go (98%) create mode 100644 fs/memwh/http.go rename fs/{memfs => memwh}/http_test.go (99%) rename fs/{memfs => memwh}/json.go (98%) rename fs/{memfs => memwh}/json_test.go (97%) rename fs/{memfs => memwh}/memfs.go (99%) rename fs/{memfs => memwh}/memfs_test.go (96%) rename fs/{memfs => memwh}/mkdirall.go (98%) rename fs/{memfs => memwh}/mkdirall_test.go (96%) rename fs/{memfs => memwh}/open.go (97%) rename fs/{memfs => memwh}/open_test.go (97%) rename fs/{memfs => memwh}/stat.go (94%) rename fs/{memfs => memwh}/stat_test.go (96%) rename fs/{memfs => memwh}/walk.go (97%) rename fs/{memfs => memwh}/walk_test.go (98%) create mode 100644 fs/mod_time.go rename fs/{fs.go => warehouse.go} (100%) diff --git a/fs/info.go b/fs/info.go index 75721db..87db439 100644 --- a/fs/info.go +++ b/fs/info.go @@ -7,24 +7,6 @@ import ( "time" ) -const timeFmt = time.RFC3339Nano - -type ModTime time.Time - -func (m ModTime) MarshalJSON() ([]byte, error) { - t := time.Time(m) - return json.Marshal(t.Format(timeFmt)) -} - -func (m *ModTime) UnmarshalJSON(b []byte) error { - t := time.Time{} - if err := json.Unmarshal(b, &t); err != nil { - return err - } - (*m) = ModTime(t) - return nil -} - type Details struct { Name string `json:"name"` Size int64 `json:"size"` diff --git a/fs/memfs/http.go b/fs/memfs/http.go deleted file mode 100644 index 8151e03..0000000 --- a/fs/memfs/http.go +++ /dev/null @@ -1 +0,0 @@ -package memfs diff --git a/fs/memfs/create.go b/fs/memwh/create.go similarity index 97% rename from fs/memfs/create.go rename to fs/memwh/create.go index b4eeb09..6d7a543 100644 --- a/fs/memfs/create.go +++ b/fs/memwh/create.go @@ -1,4 +1,4 @@ -package memfs +package memwh import ( "path/filepath" diff --git a/fs/memfs/create_test.go b/fs/memwh/create_test.go similarity index 99% rename from fs/memfs/create_test.go rename to fs/memwh/create_test.go index 1761e64..47d6526 100644 --- a/fs/memfs/create_test.go +++ b/fs/memwh/create_test.go @@ -1,4 +1,4 @@ -package memfs +package memwh // func Test_Create(t *testing.T) { // r := require.New(t) diff --git a/fs/memfs/file.go b/fs/memwh/file.go similarity index 99% rename from fs/memfs/file.go rename to fs/memwh/file.go index c6192ff..618b281 100644 --- a/fs/memfs/file.go +++ b/fs/memwh/file.go @@ -1,4 +1,4 @@ -package memfs +package memwh import ( "bytes" diff --git a/fs/memfs/file_test.go b/fs/memwh/file_test.go similarity index 98% rename from fs/memfs/file_test.go rename to fs/memwh/file_test.go index e2f4231..d625a99 100644 --- a/fs/memfs/file_test.go +++ b/fs/memwh/file_test.go @@ -1,4 +1,4 @@ -package memfs +package memwh // func Test_File_Read_Memory(t *testing.T) { // r := require.New(t) diff --git a/fs/memwh/http.go b/fs/memwh/http.go new file mode 100644 index 0000000..a9be616 --- /dev/null +++ b/fs/memwh/http.go @@ -0,0 +1 @@ +package memwh diff --git a/fs/memfs/http_test.go b/fs/memwh/http_test.go similarity index 99% rename from fs/memfs/http_test.go rename to fs/memwh/http_test.go index ba0f237..9a9ed14 100644 --- a/fs/memfs/http_test.go +++ b/fs/memwh/http_test.go @@ -1,4 +1,4 @@ -package memfs +package memwh // func Test_HTTP_Dir(t *testing.T) { // r := require.New(t) diff --git a/fs/memfs/json.go b/fs/memwh/json.go similarity index 98% rename from fs/memfs/json.go rename to fs/memwh/json.go index 31bb74d..8557cc3 100644 --- a/fs/memfs/json.go +++ b/fs/memwh/json.go @@ -1,4 +1,4 @@ -package memfs +package memwh import ( "encoding/json" diff --git a/fs/memfs/json_test.go b/fs/memwh/json_test.go similarity index 97% rename from fs/memfs/json_test.go rename to fs/memwh/json_test.go index c257cc2..7b0b9c1 100644 --- a/fs/memfs/json_test.go +++ b/fs/memwh/json_test.go @@ -1,4 +1,4 @@ -package memfs +package memwh // func Test_File_JSON(t *testing.T) { // r := require.New(t) diff --git a/fs/memfs/memfs.go b/fs/memwh/memfs.go similarity index 99% rename from fs/memfs/memfs.go rename to fs/memwh/memfs.go index 537cf82..a8d9cbb 100644 --- a/fs/memfs/memfs.go +++ b/fs/memwh/memfs.go @@ -1,4 +1,4 @@ -package memfs +package memwh import ( "fmt" diff --git a/fs/memfs/memfs_test.go b/fs/memwh/memfs_test.go similarity index 96% rename from fs/memfs/memfs_test.go rename to fs/memwh/memfs_test.go index cd27931..be388e4 100644 --- a/fs/memfs/memfs_test.go +++ b/fs/memwh/memfs_test.go @@ -1,4 +1,4 @@ -package memfs +package memwh import ( "testing" diff --git a/fs/memfs/mkdirall.go b/fs/memwh/mkdirall.go similarity index 98% rename from fs/memfs/mkdirall.go rename to fs/memwh/mkdirall.go index 1cd5c43..9694f9b 100644 --- a/fs/memfs/mkdirall.go +++ b/fs/memwh/mkdirall.go @@ -1,4 +1,4 @@ -package memfs +package memwh import ( "os" diff --git a/fs/memfs/mkdirall_test.go b/fs/memwh/mkdirall_test.go similarity index 96% rename from fs/memfs/mkdirall_test.go rename to fs/memwh/mkdirall_test.go index a9da153..6759585 100644 --- a/fs/memfs/mkdirall_test.go +++ b/fs/memwh/mkdirall_test.go @@ -1,4 +1,4 @@ -package memfs +package memwh import ( "os" diff --git a/fs/memfs/open.go b/fs/memwh/open.go similarity index 97% rename from fs/memfs/open.go rename to fs/memwh/open.go index 78f27d6..4304218 100644 --- a/fs/memfs/open.go +++ b/fs/memwh/open.go @@ -1,4 +1,4 @@ -package memfs +package memwh import ( "fmt" diff --git a/fs/memfs/open_test.go b/fs/memwh/open_test.go similarity index 97% rename from fs/memfs/open_test.go rename to fs/memwh/open_test.go index 4442bd5..5ffa5b9 100644 --- a/fs/memfs/open_test.go +++ b/fs/memwh/open_test.go @@ -1,4 +1,4 @@ -package memfs +package memwh // func Test_Open(t *testing.T) { // r := require.New(t) diff --git a/fs/memfs/stat.go b/fs/memwh/stat.go similarity index 94% rename from fs/memfs/stat.go rename to fs/memwh/stat.go index 0e9fc6f..404095e 100644 --- a/fs/memfs/stat.go +++ b/fs/memwh/stat.go @@ -1,4 +1,4 @@ -package memfs +package memwh import ( "fmt" diff --git a/fs/memfs/stat_test.go b/fs/memwh/stat_test.go similarity index 96% rename from fs/memfs/stat_test.go rename to fs/memwh/stat_test.go index 492c41c..0a6951b 100644 --- a/fs/memfs/stat_test.go +++ b/fs/memwh/stat_test.go @@ -1,4 +1,4 @@ -package memfs +package memwh // func Test_Stat(t *testing.T) { // r := require.New(t) diff --git a/fs/memfs/walk.go b/fs/memwh/walk.go similarity index 97% rename from fs/memfs/walk.go rename to fs/memwh/walk.go index 015acd5..93d3538 100644 --- a/fs/memfs/walk.go +++ b/fs/memwh/walk.go @@ -1,4 +1,4 @@ -package memfs +package memwh import ( "fmt" diff --git a/fs/memfs/walk_test.go b/fs/memwh/walk_test.go similarity index 98% rename from fs/memfs/walk_test.go rename to fs/memwh/walk_test.go index 179368a..49849a7 100644 --- a/fs/memfs/walk_test.go +++ b/fs/memwh/walk_test.go @@ -1,4 +1,4 @@ -package memfs +package memwh // func Test_Walk(t *testing.T) { // r := require.New(t) diff --git a/fs/mod_time.go b/fs/mod_time.go new file mode 100644 index 0000000..b715106 --- /dev/null +++ b/fs/mod_time.go @@ -0,0 +1,24 @@ +package fs + +import ( + "encoding/json" + "time" +) + +const timeFmt = time.RFC3339Nano + +type ModTime time.Time + +func (m ModTime) MarshalJSON() ([]byte, error) { + t := time.Time(m) + return json.Marshal(t.Format(timeFmt)) +} + +func (m *ModTime) UnmarshalJSON(b []byte) error { + t := time.Time{} + if err := json.Unmarshal(b, &t); err != nil { + return err + } + (*m) = ModTime(t) + return nil +} diff --git a/fs/fs.go b/fs/warehouse.go similarity index 100% rename from fs/fs.go rename to fs/warehouse.go From 4e3e96b0ece558aa17763d1120d7aa20fc04d703 Mon Sep 17 00:00:00 2001 From: Mark Bates Date: Sun, 1 Sep 2019 17:52:06 -0400 Subject: [PATCH 18/46] virgil's handcrafted root beer --- fs/{hdfs => hdwh}/file.go | 2 +- fs/{hdfs/hdfs.go => hdwh/hdwh.go} | 2 +- fs/{hdfs/hdfs_test.go => hdwh/hdwh_test.go} | 2 +- fs/memwh/{memfs.go => memwh.go} | 0 fs/memwh/{memfs_test.go => memwh_test.go} | 0 5 files changed, 3 insertions(+), 3 deletions(-) rename fs/{hdfs => hdwh}/file.go (98%) rename fs/{hdfs/hdfs.go => hdwh/hdwh.go} (99%) rename fs/{hdfs/hdfs_test.go => hdwh/hdwh_test.go} (96%) rename fs/memwh/{memfs.go => memwh.go} (100%) rename fs/memwh/{memfs_test.go => memwh_test.go} (100%) diff --git a/fs/hdfs/file.go b/fs/hdwh/file.go similarity index 98% rename from fs/hdfs/file.go rename to fs/hdwh/file.go index 52219f2..2349b30 100644 --- a/fs/hdfs/file.go +++ b/fs/hdwh/file.go @@ -1,4 +1,4 @@ -package hdfs +package hdwh import ( "net/http" diff --git a/fs/hdfs/hdfs.go b/fs/hdwh/hdwh.go similarity index 99% rename from fs/hdfs/hdfs.go rename to fs/hdwh/hdwh.go index e80e61f..3f89b5b 100644 --- a/fs/hdfs/hdfs.go +++ b/fs/hdwh/hdwh.go @@ -1,4 +1,4 @@ -package hdfs +package hdwh import ( "fmt" diff --git a/fs/hdfs/hdfs_test.go b/fs/hdwh/hdwh_test.go similarity index 96% rename from fs/hdfs/hdfs_test.go rename to fs/hdwh/hdwh_test.go index eeb958e..488cd36 100644 --- a/fs/hdfs/hdfs_test.go +++ b/fs/hdwh/hdwh_test.go @@ -1,4 +1,4 @@ -package hdfs +package hdwh import ( "path/filepath" diff --git a/fs/memwh/memfs.go b/fs/memwh/memwh.go similarity index 100% rename from fs/memwh/memfs.go rename to fs/memwh/memwh.go diff --git a/fs/memwh/memfs_test.go b/fs/memwh/memwh_test.go similarity index 100% rename from fs/memwh/memfs_test.go rename to fs/memwh/memwh_test.go From d3b670ed37c567b0cdb68dd8adfaaf20a38c73a2 Mon Sep 17 00:00:00 2001 From: Mark Bates Date: Sun, 1 Sep 2019 17:54:05 -0400 Subject: [PATCH 19/46] but we unleashed a lion --- fs/hdwh/hdwh.go | 34 +++++++++++++++++----------------- fs/hdwh/hdwh_test.go | 2 +- fs/memwh/create.go | 2 +- fs/memwh/http_test.go | 6 +++--- fs/memwh/memwh.go | 26 +++++++++++++------------- fs/memwh/memwh_test.go | 2 +- fs/memwh/mkdirall.go | 2 +- fs/memwh/open.go | 2 +- fs/memwh/stat.go | 2 +- fs/memwh/walk.go | 2 +- 10 files changed, 40 insertions(+), 40 deletions(-) diff --git a/fs/hdwh/hdwh.go b/fs/hdwh/hdwh.go index 3f89b5b..eb9117d 100644 --- a/fs/hdwh/hdwh.go +++ b/fs/hdwh/hdwh.go @@ -12,15 +12,15 @@ import ( "github.com/markbates/pkger/internal/maps" ) -var _ fs.Warehouse = &FS{} +var _ fs.Warehouse = &Warehouse{} -type FS struct { +type Warehouse struct { infos *maps.Infos paths *maps.Paths current here.Info } -func (f *FS) Abs(p string) (string, error) { +func (f *Warehouse) Abs(p string) (string, error) { pt, err := f.Parse(p) if err != nil { return "", err @@ -28,7 +28,7 @@ func (f *FS) Abs(p string) (string, error) { return f.AbsPath(pt) } -func (f *FS) AbsPath(pt fs.Path) (string, error) { +func (f *Warehouse) AbsPath(pt fs.Path) (string, error) { if pt.Pkg == f.current.ImportPath { return filepath.Join(f.current.Dir, pt.Name), nil } @@ -39,12 +39,12 @@ func (f *FS) AbsPath(pt fs.Path) (string, error) { return filepath.Join(info.Dir, pt.Name), nil } -func New() (*FS, error) { +func New() (*Warehouse, error) { info, err := here.Current() if err != nil { return nil, err } - return &FS{ + return &Warehouse{ infos: &maps.Infos{}, paths: &maps.Paths{ Current: info, @@ -53,7 +53,7 @@ func New() (*FS, error) { }, nil } -func (fx *FS) Create(name string) (fs.File, error) { +func (fx *Warehouse) Create(name string) (fs.File, error) { name, err := fx.Abs(name) if err != nil { return nil, err @@ -68,11 +68,11 @@ func (fx *FS) Create(name string) (fs.File, error) { return NewFile(fx, f) } -func (f *FS) Current() (here.Info, error) { +func (f *Warehouse) Current() (here.Info, error) { return f.current, nil } -func (f *FS) Info(p string) (here.Info, error) { +func (f *Warehouse) Info(p string) (here.Info, error) { info, ok := f.infos.Load(p) if ok { return info, nil @@ -86,7 +86,7 @@ func (f *FS) Info(p string) (here.Info, error) { return info, nil } -func (f *FS) MkdirAll(p string, perm os.FileMode) error { +func (f *Warehouse) MkdirAll(p string, perm os.FileMode) error { p, err := f.Abs(p) if err != nil { return err @@ -94,7 +94,7 @@ func (f *FS) MkdirAll(p string, perm os.FileMode) error { return os.MkdirAll(p, perm) } -func (fx *FS) Open(name string) (fs.File, error) { +func (fx *Warehouse) Open(name string) (fs.File, error) { name, err := fx.Abs(name) if err != nil { return nil, err @@ -106,11 +106,11 @@ func (fx *FS) Open(name string) (fs.File, error) { return NewFile(fx, f) } -func (f *FS) Parse(p string) (fs.Path, error) { +func (f *Warehouse) Parse(p string) (fs.Path, error) { return f.paths.Parse(p) } -func (f *FS) ReadFile(s string) ([]byte, error) { +func (f *Warehouse) ReadFile(s string) ([]byte, error) { s, err := f.Abs(s) if err != nil { return nil, err @@ -118,7 +118,7 @@ func (f *FS) ReadFile(s string) ([]byte, error) { return ioutil.ReadFile(s) } -func (f *FS) Stat(name string) (os.FileInfo, error) { +func (f *Warehouse) Stat(name string) (os.FileInfo, error) { pt, err := f.Parse(name) if err != nil { return nil, err @@ -139,7 +139,7 @@ func (f *FS) Stat(name string) (os.FileInfo, error) { return info, nil } -func (f *FS) Walk(p string, wf filepath.WalkFunc) error { +func (f *Warehouse) Walk(p string, wf filepath.WalkFunc) error { fp, err := f.Abs(p) if err != nil { return err @@ -165,7 +165,7 @@ func (f *FS) Walk(p string, wf filepath.WalkFunc) error { return err } -func (fx *FS) Remove(name string) error { +func (fx *Warehouse) Remove(name string) error { name, err := fx.Abs(name) if err != nil { return err @@ -173,7 +173,7 @@ func (fx *FS) Remove(name string) error { return os.Remove(name) } -func (fx *FS) RemoveAll(name string) error { +func (fx *Warehouse) RemoveAll(name string) error { name, err := fx.Abs(name) if err != nil { return err diff --git a/fs/hdwh/hdwh_test.go b/fs/hdwh/hdwh_test.go index 488cd36..20d5bb1 100644 --- a/fs/hdwh/hdwh_test.go +++ b/fs/hdwh/hdwh_test.go @@ -8,7 +8,7 @@ import ( "github.com/stretchr/testify/require" ) -func Test_FS(t *testing.T) { +func Test_Warehouse(t *testing.T) { r := require.New(t) myfs, err := New() diff --git a/fs/memwh/create.go b/fs/memwh/create.go index 6d7a543..e61a835 100644 --- a/fs/memwh/create.go +++ b/fs/memwh/create.go @@ -7,7 +7,7 @@ import ( "github.com/markbates/pkger/fs" ) -func (fx *FS) Create(name string) (fs.File, error) { +func (fx *Warehouse) Create(name string) (fs.File, error) { pt, err := fx.Parse(name) if err != nil { return nil, err diff --git a/fs/memwh/http_test.go b/fs/memwh/http_test.go index 9a9ed14..62fcae3 100644 --- a/fs/memwh/http_test.go +++ b/fs/memwh/http_test.go @@ -3,7 +3,7 @@ package memwh // func Test_HTTP_Dir(t *testing.T) { // r := require.New(t) // -// fs := NewFS() +// fs := NewWarehouse() // // r.NoError(Folder.Create(fs)) // @@ -24,7 +24,7 @@ package memwh // func Test_HTTP_File_Memory(t *testing.T) { // r := require.New(t) // -// fs := NewFS() +// fs := NewWarehouse() // r.NoError(Folder.Create(fs)) // // dir, err := fs.Open("/") @@ -44,7 +44,7 @@ package memwh // func Test_HTTP_Dir_Memory_StripPrefix(t *testing.T) { // r := require.New(t) // -// fs := NewFS() +// fs := NewWarehouse() // r.NoError(Folder.Create(fs)) // // dir, err := fs.Open("/public") diff --git a/fs/memwh/memwh.go b/fs/memwh/memwh.go index a8d9cbb..815adbf 100644 --- a/fs/memwh/memwh.go +++ b/fs/memwh/memwh.go @@ -11,16 +11,16 @@ import ( "github.com/markbates/pkger/internal/maps" ) -var _ fs.Warehouse = &FS{} +var _ fs.Warehouse = &Warehouse{} -func WithInfo(fx *FS, infos ...here.Info) { +func WithInfo(fx *Warehouse, infos ...here.Info) { for _, info := range infos { fx.infos.Store(info.ImportPath, info) } } -func New(info here.Info) (*FS, error) { - f := &FS{ +func New(info here.Info) (*Warehouse, error) { + f := &Warehouse{ infos: &maps.Infos{}, paths: &maps.Paths{ Current: info, @@ -31,14 +31,14 @@ func New(info here.Info) (*FS, error) { return f, nil } -type FS struct { +type Warehouse struct { infos *maps.Infos paths *maps.Paths files *maps.Files current here.Info } -func (f *FS) Abs(p string) (string, error) { +func (f *Warehouse) Abs(p string) (string, error) { pt, err := f.Parse(p) if err != nil { return "", err @@ -46,15 +46,15 @@ func (f *FS) Abs(p string) (string, error) { return f.AbsPath(pt) } -func (f *FS) AbsPath(pt fs.Path) (string, error) { +func (f *Warehouse) AbsPath(pt fs.Path) (string, error) { return pt.String(), nil } -func (f *FS) Current() (here.Info, error) { +func (f *Warehouse) Current() (here.Info, error) { return f.current, nil } -func (f *FS) Info(p string) (here.Info, error) { +func (f *Warehouse) Info(p string) (here.Info, error) { info, ok := f.infos.Load(p) if !ok { return info, fmt.Errorf("no such package %q", p) @@ -63,11 +63,11 @@ func (f *FS) Info(p string) (here.Info, error) { return info, nil } -func (f *FS) Parse(p string) (fs.Path, error) { +func (f *Warehouse) Parse(p string) (fs.Path, error) { return f.paths.Parse(p) } -func (fx *FS) ReadFile(s string) ([]byte, error) { +func (fx *Warehouse) ReadFile(s string) ([]byte, error) { f, err := fx.Open(s) if err != nil { return nil, err @@ -76,7 +76,7 @@ func (fx *FS) ReadFile(s string) ([]byte, error) { return ioutil.ReadAll(f) } -func (fx *FS) Remove(name string) error { +func (fx *Warehouse) Remove(name string) error { pt, err := fx.Parse(name) if err != nil { return err @@ -90,7 +90,7 @@ func (fx *FS) Remove(name string) error { return nil } -func (fx *FS) RemoveAll(name string) error { +func (fx *Warehouse) RemoveAll(name string) error { pt, err := fx.Parse(name) if err != nil { return err diff --git a/fs/memwh/memwh_test.go b/fs/memwh/memwh_test.go index be388e4..1927e2d 100644 --- a/fs/memwh/memwh_test.go +++ b/fs/memwh/memwh_test.go @@ -8,7 +8,7 @@ import ( "github.com/stretchr/testify/require" ) -func Test_FS(t *testing.T) { +func Test_Warehouse(t *testing.T) { r := require.New(t) info, err := here.Current() diff --git a/fs/memwh/mkdirall.go b/fs/memwh/mkdirall.go index 9694f9b..970917b 100644 --- a/fs/memwh/mkdirall.go +++ b/fs/memwh/mkdirall.go @@ -8,7 +8,7 @@ import ( "github.com/markbates/pkger/fs" ) -func (fx *FS) MkdirAll(p string, perm os.FileMode) error { +func (fx *Warehouse) MkdirAll(p string, perm os.FileMode) error { path, err := fx.Parse(p) if err != nil { return err diff --git a/fs/memwh/open.go b/fs/memwh/open.go index 4304218..671fd43 100644 --- a/fs/memwh/open.go +++ b/fs/memwh/open.go @@ -6,7 +6,7 @@ import ( "github.com/markbates/pkger/fs" ) -func (fx *FS) Open(name string) (fs.File, error) { +func (fx *Warehouse) Open(name string) (fs.File, error) { pt, err := fx.Parse(name) if err != nil { return nil, err diff --git a/fs/memwh/stat.go b/fs/memwh/stat.go index 404095e..af1af38 100644 --- a/fs/memwh/stat.go +++ b/fs/memwh/stat.go @@ -5,7 +5,7 @@ import ( "os" ) -func (fx *FS) Stat(name string) (os.FileInfo, error) { +func (fx *Warehouse) Stat(name string) (os.FileInfo, error) { pt, err := fx.Parse(name) if err != nil { return nil, err diff --git a/fs/memwh/walk.go b/fs/memwh/walk.go index 93d3538..272d4ee 100644 --- a/fs/memwh/walk.go +++ b/fs/memwh/walk.go @@ -8,7 +8,7 @@ import ( "github.com/markbates/pkger/fs" ) -func (f *FS) Walk(p string, wf filepath.WalkFunc) error { +func (f *Warehouse) Walk(p string, wf filepath.WalkFunc) error { keys := f.files.Keys() pt, err := f.Parse(p) From 6cf3685ec7f176e5af47efb60d5b7bdd08969781 Mon Sep 17 00:00:00 2001 From: Mark Bates Date: Sun, 1 Sep 2019 17:55:17 -0400 Subject: [PATCH 20/46] jeremy spoke in class today --- fs/hdwh/{hdwh.go => warehouse.go} | 0 fs/hdwh/{hdwh_test.go => warehouse_test.go} | 0 fs/memwh/{memwh.go => warehouse.go} | 0 fs/memwh/{memwh_test.go => warehouse_test.go} | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename fs/hdwh/{hdwh.go => warehouse.go} (100%) rename fs/hdwh/{hdwh_test.go => warehouse_test.go} (100%) rename fs/memwh/{memwh.go => warehouse.go} (100%) rename fs/memwh/{memwh_test.go => warehouse_test.go} (100%) diff --git a/fs/hdwh/hdwh.go b/fs/hdwh/warehouse.go similarity index 100% rename from fs/hdwh/hdwh.go rename to fs/hdwh/warehouse.go diff --git a/fs/hdwh/hdwh_test.go b/fs/hdwh/warehouse_test.go similarity index 100% rename from fs/hdwh/hdwh_test.go rename to fs/hdwh/warehouse_test.go diff --git a/fs/memwh/memwh.go b/fs/memwh/warehouse.go similarity index 100% rename from fs/memwh/memwh.go rename to fs/memwh/warehouse.go diff --git a/fs/memwh/memwh_test.go b/fs/memwh/warehouse_test.go similarity index 100% rename from fs/memwh/memwh_test.go rename to fs/memwh/warehouse_test.go From d2fa5f9f730fdf43307d0d5a675baeb0c69b679b Mon Sep 17 00:00:00 2001 From: Mark Bates Date: Sun, 1 Sep 2019 17:58:20 -0400 Subject: [PATCH 21/46] old king's road --- fs/{memwh => memware}/create.go | 2 +- fs/{memwh => memware}/create_test.go | 2 +- fs/{memwh => memware}/file.go | 2 +- fs/{memwh => memware}/file_test.go | 2 +- fs/memware/http.go | 1 + fs/{memwh => memware}/http_test.go | 2 +- fs/{memwh => memware}/json.go | 2 +- fs/{memwh => memware}/json_test.go | 2 +- fs/{memwh => memware}/mkdirall.go | 2 +- fs/{memwh => memware}/mkdirall_test.go | 2 +- fs/{memwh => memware}/open.go | 2 +- fs/{memwh => memware}/open_test.go | 2 +- fs/{memwh => memware}/stat.go | 2 +- fs/{memwh => memware}/stat_test.go | 2 +- fs/{memwh => memware}/walk.go | 2 +- fs/{memwh => memware}/walk_test.go | 2 +- fs/{memwh => memware}/warehouse.go | 2 +- fs/{memwh => memware}/warehouse_test.go | 2 +- fs/memwh/http.go | 1 - fs/{hdwh => osware}/file.go | 2 +- fs/{hdwh => osware}/warehouse.go | 2 +- fs/{hdwh => osware}/warehouse_test.go | 2 +- 22 files changed, 21 insertions(+), 21 deletions(-) rename fs/{memwh => memware}/create.go (97%) rename fs/{memwh => memware}/create_test.go (99%) rename fs/{memwh => memware}/file.go (99%) rename fs/{memwh => memware}/file_test.go (98%) create mode 100644 fs/memware/http.go rename fs/{memwh => memware}/http_test.go (99%) rename fs/{memwh => memware}/json.go (98%) rename fs/{memwh => memware}/json_test.go (97%) rename fs/{memwh => memware}/mkdirall.go (98%) rename fs/{memwh => memware}/mkdirall_test.go (96%) rename fs/{memwh => memware}/open.go (96%) rename fs/{memwh => memware}/open_test.go (96%) rename fs/{memwh => memware}/stat.go (94%) rename fs/{memwh => memware}/stat_test.go (95%) rename fs/{memwh => memware}/walk.go (97%) rename fs/{memwh => memware}/walk_test.go (98%) rename fs/{memwh => memware}/warehouse.go (99%) rename fs/{memwh => memware}/warehouse_test.go (96%) delete mode 100644 fs/memwh/http.go rename fs/{hdwh => osware}/file.go (98%) rename fs/{hdwh => osware}/warehouse.go (99%) rename fs/{hdwh => osware}/warehouse_test.go (96%) diff --git a/fs/memwh/create.go b/fs/memware/create.go similarity index 97% rename from fs/memwh/create.go rename to fs/memware/create.go index e61a835..55fd12f 100644 --- a/fs/memwh/create.go +++ b/fs/memware/create.go @@ -1,4 +1,4 @@ -package memwh +package memware import ( "path/filepath" diff --git a/fs/memwh/create_test.go b/fs/memware/create_test.go similarity index 99% rename from fs/memwh/create_test.go rename to fs/memware/create_test.go index 47d6526..bcab262 100644 --- a/fs/memwh/create_test.go +++ b/fs/memware/create_test.go @@ -1,4 +1,4 @@ -package memwh +package memware // func Test_Create(t *testing.T) { // r := require.New(t) diff --git a/fs/memwh/file.go b/fs/memware/file.go similarity index 99% rename from fs/memwh/file.go rename to fs/memware/file.go index 618b281..7e156d0 100644 --- a/fs/memwh/file.go +++ b/fs/memware/file.go @@ -1,4 +1,4 @@ -package memwh +package memware import ( "bytes" diff --git a/fs/memwh/file_test.go b/fs/memware/file_test.go similarity index 98% rename from fs/memwh/file_test.go rename to fs/memware/file_test.go index d625a99..87c636f 100644 --- a/fs/memwh/file_test.go +++ b/fs/memware/file_test.go @@ -1,4 +1,4 @@ -package memwh +package memware // func Test_File_Read_Memory(t *testing.T) { // r := require.New(t) diff --git a/fs/memware/http.go b/fs/memware/http.go new file mode 100644 index 0000000..2ed2560 --- /dev/null +++ b/fs/memware/http.go @@ -0,0 +1 @@ +package memware diff --git a/fs/memwh/http_test.go b/fs/memware/http_test.go similarity index 99% rename from fs/memwh/http_test.go rename to fs/memware/http_test.go index 62fcae3..a075de8 100644 --- a/fs/memwh/http_test.go +++ b/fs/memware/http_test.go @@ -1,4 +1,4 @@ -package memwh +package memware // func Test_HTTP_Dir(t *testing.T) { // r := require.New(t) diff --git a/fs/memwh/json.go b/fs/memware/json.go similarity index 98% rename from fs/memwh/json.go rename to fs/memware/json.go index 8557cc3..90a9d41 100644 --- a/fs/memwh/json.go +++ b/fs/memware/json.go @@ -1,4 +1,4 @@ -package memwh +package memware import ( "encoding/json" diff --git a/fs/memwh/json_test.go b/fs/memware/json_test.go similarity index 97% rename from fs/memwh/json_test.go rename to fs/memware/json_test.go index 7b0b9c1..585f109 100644 --- a/fs/memwh/json_test.go +++ b/fs/memware/json_test.go @@ -1,4 +1,4 @@ -package memwh +package memware // func Test_File_JSON(t *testing.T) { // r := require.New(t) diff --git a/fs/memwh/mkdirall.go b/fs/memware/mkdirall.go similarity index 98% rename from fs/memwh/mkdirall.go rename to fs/memware/mkdirall.go index 970917b..e426800 100644 --- a/fs/memwh/mkdirall.go +++ b/fs/memware/mkdirall.go @@ -1,4 +1,4 @@ -package memwh +package memware import ( "os" diff --git a/fs/memwh/mkdirall_test.go b/fs/memware/mkdirall_test.go similarity index 96% rename from fs/memwh/mkdirall_test.go rename to fs/memware/mkdirall_test.go index 6759585..fa3f4df 100644 --- a/fs/memwh/mkdirall_test.go +++ b/fs/memware/mkdirall_test.go @@ -1,4 +1,4 @@ -package memwh +package memware import ( "os" diff --git a/fs/memwh/open.go b/fs/memware/open.go similarity index 96% rename from fs/memwh/open.go rename to fs/memware/open.go index 671fd43..d4e5a7e 100644 --- a/fs/memwh/open.go +++ b/fs/memware/open.go @@ -1,4 +1,4 @@ -package memwh +package memware import ( "fmt" diff --git a/fs/memwh/open_test.go b/fs/memware/open_test.go similarity index 96% rename from fs/memwh/open_test.go rename to fs/memware/open_test.go index 5ffa5b9..288fd73 100644 --- a/fs/memwh/open_test.go +++ b/fs/memware/open_test.go @@ -1,4 +1,4 @@ -package memwh +package memware // func Test_Open(t *testing.T) { // r := require.New(t) diff --git a/fs/memwh/stat.go b/fs/memware/stat.go similarity index 94% rename from fs/memwh/stat.go rename to fs/memware/stat.go index af1af38..2711a3e 100644 --- a/fs/memwh/stat.go +++ b/fs/memware/stat.go @@ -1,4 +1,4 @@ -package memwh +package memware import ( "fmt" diff --git a/fs/memwh/stat_test.go b/fs/memware/stat_test.go similarity index 95% rename from fs/memwh/stat_test.go rename to fs/memware/stat_test.go index 0a6951b..b4dd5c2 100644 --- a/fs/memwh/stat_test.go +++ b/fs/memware/stat_test.go @@ -1,4 +1,4 @@ -package memwh +package memware // func Test_Stat(t *testing.T) { // r := require.New(t) diff --git a/fs/memwh/walk.go b/fs/memware/walk.go similarity index 97% rename from fs/memwh/walk.go rename to fs/memware/walk.go index 272d4ee..2836ff6 100644 --- a/fs/memwh/walk.go +++ b/fs/memware/walk.go @@ -1,4 +1,4 @@ -package memwh +package memware import ( "fmt" diff --git a/fs/memwh/walk_test.go b/fs/memware/walk_test.go similarity index 98% rename from fs/memwh/walk_test.go rename to fs/memware/walk_test.go index 49849a7..0d45c10 100644 --- a/fs/memwh/walk_test.go +++ b/fs/memware/walk_test.go @@ -1,4 +1,4 @@ -package memwh +package memware // func Test_Walk(t *testing.T) { // r := require.New(t) diff --git a/fs/memwh/warehouse.go b/fs/memware/warehouse.go similarity index 99% rename from fs/memwh/warehouse.go rename to fs/memware/warehouse.go index 815adbf..6b59a52 100644 --- a/fs/memwh/warehouse.go +++ b/fs/memware/warehouse.go @@ -1,4 +1,4 @@ -package memwh +package memware import ( "fmt" diff --git a/fs/memwh/warehouse_test.go b/fs/memware/warehouse_test.go similarity index 96% rename from fs/memwh/warehouse_test.go rename to fs/memware/warehouse_test.go index 1927e2d..2184752 100644 --- a/fs/memwh/warehouse_test.go +++ b/fs/memware/warehouse_test.go @@ -1,4 +1,4 @@ -package memwh +package memware import ( "testing" diff --git a/fs/memwh/http.go b/fs/memwh/http.go deleted file mode 100644 index a9be616..0000000 --- a/fs/memwh/http.go +++ /dev/null @@ -1 +0,0 @@ -package memwh diff --git a/fs/hdwh/file.go b/fs/osware/file.go similarity index 98% rename from fs/hdwh/file.go rename to fs/osware/file.go index 2349b30..fba1713 100644 --- a/fs/hdwh/file.go +++ b/fs/osware/file.go @@ -1,4 +1,4 @@ -package hdwh +package hdware import ( "net/http" diff --git a/fs/hdwh/warehouse.go b/fs/osware/warehouse.go similarity index 99% rename from fs/hdwh/warehouse.go rename to fs/osware/warehouse.go index eb9117d..b16f21a 100644 --- a/fs/hdwh/warehouse.go +++ b/fs/osware/warehouse.go @@ -1,4 +1,4 @@ -package hdwh +package hdware import ( "fmt" diff --git a/fs/hdwh/warehouse_test.go b/fs/osware/warehouse_test.go similarity index 96% rename from fs/hdwh/warehouse_test.go rename to fs/osware/warehouse_test.go index 20d5bb1..398934e 100644 --- a/fs/hdwh/warehouse_test.go +++ b/fs/osware/warehouse_test.go @@ -1,4 +1,4 @@ -package hdwh +package hdware import ( "path/filepath" From 3d94a20bbfff81fd4d9cf9bf16681dc321c9e435 Mon Sep 17 00:00:00 2001 From: Mark Bates Date: Sun, 1 Sep 2019 18:02:45 -0400 Subject: [PATCH 22/46] bottles and flowers --- fs/fstest/file.go | 12 ------- fs/osware/warehouse_test.go | 24 ------------- internal/maps/files.go | 44 ++++++++++++------------ internal/maps/paths.go | 30 ++++++++-------- {fs => pkging}/file.go | 2 +- {fs => pkging}/info.go | 2 +- {fs => pkging}/memware/create.go | 12 +++---- {fs => pkging}/memware/create_test.go | 0 {fs => pkging}/memware/file.go | 36 +++++++++---------- {fs => pkging}/memware/file_test.go | 0 {fs => pkging}/memware/http.go | 0 {fs => pkging}/memware/http_test.go | 0 {fs => pkging}/memware/json.go | 4 +-- {fs => pkging}/memware/json_test.go | 0 {fs => pkging}/memware/mkdirall.go | 16 ++++----- {fs => pkging}/memware/mkdirall_test.go | 0 {fs => pkging}/memware/open.go | 14 ++++---- {fs => pkging}/memware/open_test.go | 0 {fs => pkging}/memware/stat.go | 0 {fs => pkging}/memware/stat_test.go | 0 {fs => pkging}/memware/walk.go | 4 +-- {fs => pkging}/memware/walk_test.go | 0 {fs => pkging}/memware/warehouse.go | 8 ++--- {fs => pkging}/memware/warehouse_test.go | 8 ++--- {fs => pkging}/mod_time.go | 2 +- {fs => pkging}/osware/file.go | 28 +++++++-------- {fs => pkging}/osware/warehouse.go | 16 ++++----- pkging/osware/warehouse_test.go | 24 +++++++++++++ {fs => pkging}/path.go | 2 +- {fs => pkging}/warehouse.go | 2 +- pkging/waretest/file.go | 12 +++++++ {fs/fstest => pkging/waretest}/fstest.go | 6 ++-- {fs/fstest => pkging/waretest}/suite.go | 30 ++++++++-------- 33 files changed, 169 insertions(+), 169 deletions(-) delete mode 100644 fs/fstest/file.go delete mode 100644 fs/osware/warehouse_test.go rename {fs => pkging}/file.go (96%) rename {fs => pkging}/info.go (99%) rename {fs => pkging}/memware/create.go (66%) rename {fs => pkging}/memware/create_test.go (100%) rename {fs => pkging}/memware/file.go (79%) rename {fs => pkging}/memware/file_test.go (100%) rename {fs => pkging}/memware/http.go (100%) rename {fs => pkging}/memware/http_test.go (100%) rename {fs => pkging}/memware/json.go (94%) rename {fs => pkging}/memware/json_test.go (100%) rename {fs => pkging}/memware/mkdirall.go (78%) rename {fs => pkging}/memware/mkdirall_test.go (100%) rename {fs => pkging}/memware/open.go (59%) rename {fs => pkging}/memware/open_test.go (100%) rename {fs => pkging}/memware/stat.go (100%) rename {fs => pkging}/memware/stat_test.go (100%) rename {fs => pkging}/memware/walk.go (83%) rename {fs => pkging}/memware/walk_test.go (100%) rename {fs => pkging}/memware/warehouse.go (91%) rename {fs => pkging}/memware/warehouse_test.go (66%) rename {fs => pkging}/mod_time.go (96%) rename {fs => pkging}/osware/file.go (69%) rename {fs => pkging}/osware/warehouse.go (86%) create mode 100644 pkging/osware/warehouse_test.go rename {fs => pkging}/path.go (97%) rename {fs => pkging}/warehouse.go (99%) create mode 100644 pkging/waretest/file.go rename {fs/fstest => pkging/waretest}/fstest.go (77%) rename {fs/fstest => pkging/waretest}/suite.go (85%) diff --git a/fs/fstest/file.go b/fs/fstest/file.go deleted file mode 100644 index 7c61646..0000000 --- a/fs/fstest/file.go +++ /dev/null @@ -1,12 +0,0 @@ -package fstest - -import ( - "github.com/markbates/pkger/fs" -) - -type TestFile struct { - Name string - Path fs.Path -} - -type TestFiles map[fs.Path]TestFile diff --git a/fs/osware/warehouse_test.go b/fs/osware/warehouse_test.go deleted file mode 100644 index 398934e..0000000 --- a/fs/osware/warehouse_test.go +++ /dev/null @@ -1,24 +0,0 @@ -package hdware - -import ( - "path/filepath" - "testing" - - "github.com/markbates/pkger/fs/fstest" - "github.com/stretchr/testify/require" -) - -func Test_Warehouse(t *testing.T) { - r := require.New(t) - - myfs, err := New() - r.NoError(err) - - myfs.current.Dir = filepath.Join(myfs.current.Dir, ".fstest") - myfs.paths.Current = myfs.current - - suite, err := fstest.NewSuite(myfs) - r.NoError(err) - - suite.Test(t) -} diff --git a/internal/maps/files.go b/internal/maps/files.go index c30170f..ddd3ccd 100644 --- a/internal/maps/files.go +++ b/internal/maps/files.go @@ -8,12 +8,12 @@ import ( "sort" "sync" - "github.com/markbates/pkger/fs" + "github.com/markbates/pkger/pkging" ) // Files wraps sync.Map and uses the following types: -// key: fs.Path -// value: fs.File +// key: pkging.Path +// value: pkging.File type Files struct { data *sync.Map once *sync.Once @@ -52,13 +52,13 @@ func (m *Files) MarshalJSON() ([]byte, error) { } func (m *Files) UnmarshalJSON(b []byte) error { - mm := map[string]fs.File{} + mm := map[string]pkging.File{} if err := json.Unmarshal(b, &mm); err != nil { return err } for k, v := range mm { - var pt fs.Path + var pt pkging.Path if err := json.Unmarshal([]byte(k), &pt); err != nil { return err } @@ -68,34 +68,34 @@ func (m *Files) UnmarshalJSON(b []byte) error { } // Delete the key from the map -func (m *Files) Delete(key fs.Path) { +func (m *Files) Delete(key pkging.Path) { m.Data().Delete(key) } // Load the key from the map. -// Returns fs.File or bool. +// Returns pkging.File or bool. // A false return indicates either the key was not found -// or the value is not of type fs.File -func (m *Files) Load(key fs.Path) (fs.File, bool) { +// or the value is not of type pkging.File +func (m *Files) Load(key pkging.Path) (pkging.File, bool) { i, ok := m.Data().Load(key) if !ok { return nil, false } - s, ok := i.(fs.File) + s, ok := i.(pkging.File) return s, ok } // LoadOrStore will return an existing key or // store the value if not already in the map -func (m *Files) LoadOrStore(key fs.Path, value fs.File) (fs.File, bool) { +func (m *Files) LoadOrStore(key pkging.Path, value pkging.File) (pkging.File, bool) { i, _ := m.Data().LoadOrStore(key, value) - s, ok := i.(fs.File) + s, ok := i.(pkging.File) return s, ok } // LoadOr will return an existing key or // run the function and store the results -func (m *Files) LoadOr(key fs.Path, fn func(*Files) (fs.File, bool)) (fs.File, bool) { +func (m *Files) LoadOr(key pkging.Path, fn func(*Files) (pkging.File, bool)) (pkging.File, bool) { i, ok := m.Load(key) if ok { return i, ok @@ -108,14 +108,14 @@ func (m *Files) LoadOr(key fs.Path, fn func(*Files) (fs.File, bool)) (fs.File, b return i, false } -// Range over the fs.File values in the map -func (m *Files) Range(f func(key fs.Path, value fs.File) bool) { +// Range over the pkging.File values in the map +func (m *Files) Range(f func(key pkging.Path, value pkging.File) bool) { m.Data().Range(func(k, v interface{}) bool { - key, ok := k.(fs.Path) + key, ok := k.(pkging.Path) if !ok { return false } - value, ok := v.(fs.File) + value, ok := v.(pkging.File) if !ok { return false } @@ -123,15 +123,15 @@ func (m *Files) Range(f func(key fs.Path, value fs.File) bool) { }) } -// Store a fs.File in the map -func (m *Files) Store(key fs.Path, value fs.File) { +// Store a pkging.File in the map +func (m *Files) Store(key pkging.Path, value pkging.File) { m.Data().Store(key, value) } // Keys returns a list of keys in the map -func (m *Files) Keys() []fs.Path { - var keys []fs.Path - m.Range(func(key fs.Path, value fs.File) bool { +func (m *Files) Keys() []pkging.Path { + var keys []pkging.Path + m.Range(func(key pkging.Path, value pkging.File) bool { keys = append(keys, key) return true }) diff --git a/internal/maps/paths.go b/internal/maps/paths.go index aee61f8..e114c5e 100644 --- a/internal/maps/paths.go +++ b/internal/maps/paths.go @@ -10,8 +10,8 @@ import ( "strings" "sync" - "github.com/markbates/pkger/fs" "github.com/markbates/pkger/here" + "github.com/markbates/pkger/pkging" ) // Paths wraps sync.Map and uses the following types: @@ -45,7 +45,7 @@ func (m *Paths) MarshalJSON() ([]byte, error) { } func (m *Paths) UnmarshalJSON(b []byte) error { - mm := map[string]fs.Path{} + mm := map[string]pkging.Path{} if err := json.Unmarshal(b, &mm); err != nil { return err @@ -65,26 +65,26 @@ func (m *Paths) Delete(key string) { // Returns Path or bool. // A false return indicates either the key was not found // or the value is not of type Path -func (m *Paths) Load(key string) (fs.Path, bool) { +func (m *Paths) Load(key string) (pkging.Path, bool) { i, ok := m.Data().Load(key) if !ok { - return fs.Path{}, false + return pkging.Path{}, false } - s, ok := i.(fs.Path) + s, ok := i.(pkging.Path) return s, ok } // LoadOrStore will return an existing key or // store the value if not already in the map -func (m *Paths) LoadOrStore(key string, value fs.Path) (fs.Path, bool) { +func (m *Paths) LoadOrStore(key string, value pkging.Path) (pkging.Path, bool) { i, _ := m.Data().LoadOrStore(key, value) - s, ok := i.(fs.Path) + s, ok := i.(pkging.Path) return s, ok } // LoadOr will return an existing key or // run the function and store the results -func (m *Paths) LoadOr(key string, fn func(*Paths) (fs.Path, bool)) (fs.Path, bool) { +func (m *Paths) LoadOr(key string, fn func(*Paths) (pkging.Path, bool)) (pkging.Path, bool) { i, ok := m.Load(key) if ok { return i, ok @@ -98,13 +98,13 @@ func (m *Paths) LoadOr(key string, fn func(*Paths) (fs.Path, bool)) (fs.Path, bo } // Range over the Path values in the map -func (m *Paths) Range(f func(key string, value fs.Path) bool) { +func (m *Paths) Range(f func(key string, value pkging.Path) bool) { m.Data().Range(func(k, v interface{}) bool { key, ok := k.(string) if !ok { return false } - value, ok := v.(fs.Path) + value, ok := v.(pkging.Path) if !ok { return false } @@ -113,14 +113,14 @@ func (m *Paths) Range(f func(key string, value fs.Path) bool) { } // Store a Path in the map -func (m *Paths) Store(key string, value fs.Path) { +func (m *Paths) Store(key string, value pkging.Path) { m.Data().Store(key, value) } // Keys returns a list of keys in the map func (m *Paths) Keys() []string { var keys []string - m.Range(func(key string, value fs.Path) bool { + m.Range(func(key string, value pkging.Path) bool { keys = append(keys, key) return true }) @@ -128,7 +128,7 @@ func (m *Paths) Keys() []string { return keys } -func (m *Paths) Parse(p string) (fs.Path, error) { +func (m *Paths) Parse(p string) (pkging.Path, error) { p = strings.Replace(p, "\\", "/", -1) p = strings.TrimSpace(p) @@ -156,8 +156,8 @@ func (m *Paths) Parse(p string) (fs.Path, error) { var pathrx = regexp.MustCompile("([^:]+)(:(/.+))?") -func (m *Paths) build(p, pkg, name string) (fs.Path, error) { - pt := fs.Path{ +func (m *Paths) build(p, pkg, name string) (pkging.Path, error) { + pt := pkging.Path{ Pkg: pkg, Name: name, } diff --git a/fs/file.go b/pkging/file.go similarity index 96% rename from fs/file.go rename to pkging/file.go index 428c51f..1fad69d 100644 --- a/fs/file.go +++ b/pkging/file.go @@ -1,4 +1,4 @@ -package fs +package pkging import ( "net/http" diff --git a/fs/info.go b/pkging/info.go similarity index 99% rename from fs/info.go rename to pkging/info.go index 87db439..3e6e97a 100644 --- a/fs/info.go +++ b/pkging/info.go @@ -1,4 +1,4 @@ -package fs +package pkging import ( "encoding/json" diff --git a/fs/memware/create.go b/pkging/memware/create.go similarity index 66% rename from fs/memware/create.go rename to pkging/memware/create.go index 55fd12f..eccef75 100644 --- a/fs/memware/create.go +++ b/pkging/memware/create.go @@ -4,10 +4,10 @@ import ( "path/filepath" "time" - "github.com/markbates/pkger/fs" + "github.com/markbates/pkger/pkging" ) -func (fx *Warehouse) Create(name string) (fs.File, error) { +func (fx *Warehouse) Create(name string) (pkging.File, error) { pt, err := fx.Parse(name) if err != nil { return nil, err @@ -20,14 +20,14 @@ func (fx *Warehouse) Create(name string) (fs.File, error) { f := &File{ path: pt, her: her, - info: &fs.FileInfo{ - Details: fs.Details{ + info: &pkging.FileInfo{ + Details: pkging.Details{ Name: pt.Name, Mode: 0644, - ModTime: fs.ModTime(time.Now()), + ModTime: pkging.ModTime(time.Now()), }, }, - fs: fx, + pkging: fx, } fx.files.Store(pt, f) diff --git a/fs/memware/create_test.go b/pkging/memware/create_test.go similarity index 100% rename from fs/memware/create_test.go rename to pkging/memware/create_test.go diff --git a/fs/memware/file.go b/pkging/memware/file.go similarity index 79% rename from fs/memware/file.go rename to pkging/memware/file.go index 7e156d0..b5b89f5 100644 --- a/fs/memware/file.go +++ b/pkging/memware/file.go @@ -11,28 +11,28 @@ import ( "strings" "time" - "github.com/markbates/pkger/fs" "github.com/markbates/pkger/here" + "github.com/markbates/pkger/pkging" ) const timeFmt = time.RFC3339Nano -var _ fs.File = &File{} +var _ pkging.File = &File{} type File struct { - info *fs.FileInfo + info *pkging.FileInfo her here.Info - path fs.Path + path pkging.Path data []byte - parent fs.Path + parent pkging.Path writer *bytes.Buffer reader io.Reader - fs fs.Warehouse + pkging pkging.Warehouse } -func (f *File) Seek(offset int64, whence int) (int64, error) { +func (f *File) Seek(ofpkginget int64, whence int) (int64, error) { if sk, ok := f.reader.(io.Seeker); ok { - return sk.Seek(offset, whence) + return sk.Seek(ofpkginget, whence) } return 0, nil } @@ -58,7 +58,7 @@ func (f *File) Close() error { fi := f.info fi.Details.Size = int64(len(f.data)) - fi.Details.ModTime = fs.ModTime(time.Now()) + fi.Details.ModTime = pkging.ModTime(time.Now()) f.info = fi return nil } @@ -99,10 +99,10 @@ func (f File) Name() string { } func (f File) Abs() (string, error) { - return f.fs.AbsPath(f.Path()) + return f.pkging.AbsPath(f.Path()) } -func (f File) Path() fs.Path { +func (f File) Path() pkging.Path { return f.path } @@ -133,7 +133,7 @@ func (f File) Format(st fmt.State, verb rune) { func (f *File) Readdir(count int) ([]os.FileInfo, error) { var infos []os.FileInfo root := f.Path().String() - err := f.fs.Walk(root, func(path string, info os.FileInfo, err error) error { + err := f.pkging.Walk(root, func(path string, info os.FileInfo, err error) error { if err != nil { return err } @@ -142,7 +142,7 @@ func (f *File) Readdir(count int) ([]os.FileInfo, error) { return io.EOF } - pt, err := f.fs.Parse(path) + pt, err := f.pkging.Parse(path) if err != nil { return err } @@ -150,7 +150,7 @@ func (f *File) Readdir(count int) ([]os.FileInfo, error) { return nil } // if f.parent.Name != "/" { - info = fs.WithName(strings.TrimPrefix(info.Name(), f.parent.Name), info) + info = pkging.WithName(strings.TrimPrefix(info.Name(), f.parent.Name), info) // } infos = append(infos, info) return nil @@ -169,7 +169,7 @@ func (f *File) Readdir(count int) ([]os.FileInfo, error) { } func (f *File) Open(name string) (http.File, error) { - pt, err := f.fs.Parse(name) + pt, err := f.pkging.Parse(name) if err != nil { return nil, err } @@ -180,7 +180,7 @@ func (f *File) Open(name string) (http.File, error) { pt.Name = path.Join(f.Path().Name, pt.Name) - di, err := f.fs.Open(pt.String()) + di, err := f.pkging.Open(pt.String()) if err != nil { return nil, err } @@ -191,11 +191,11 @@ func (f *File) Open(name string) (http.File, error) { } if fi.IsDir() { d2 := &File{ - info: fs.NewFileInfo(fi), + info: pkging.NewFileInfo(fi), her: di.Info(), path: pt, parent: f.path, - fs: f.fs, + pkging: f.pkging, } di = d2 } diff --git a/fs/memware/file_test.go b/pkging/memware/file_test.go similarity index 100% rename from fs/memware/file_test.go rename to pkging/memware/file_test.go diff --git a/fs/memware/http.go b/pkging/memware/http.go similarity index 100% rename from fs/memware/http.go rename to pkging/memware/http.go diff --git a/fs/memware/http_test.go b/pkging/memware/http_test.go similarity index 100% rename from fs/memware/http_test.go rename to pkging/memware/http_test.go diff --git a/fs/memware/json.go b/pkging/memware/json.go similarity index 94% rename from fs/memware/json.go rename to pkging/memware/json.go index 90a9d41..717d830 100644 --- a/fs/memware/json.go +++ b/pkging/memware/json.go @@ -4,7 +4,7 @@ import ( "encoding/json" "fmt" - "github.com/markbates/pkger/fs" + "github.com/markbates/pkger/pkging" ) func (f File) MarshalJSON() ([]byte, error) { @@ -29,7 +29,7 @@ func (f *File) UnmarshalJSON(b []byte) error { return fmt.Errorf("missing info") } - f.info = &fs.FileInfo{} + f.info = &pkging.FileInfo{} if err := json.Unmarshal(info, f.info); err != nil { return err } diff --git a/fs/memware/json_test.go b/pkging/memware/json_test.go similarity index 100% rename from fs/memware/json_test.go rename to pkging/memware/json_test.go diff --git a/fs/memware/mkdirall.go b/pkging/memware/mkdirall.go similarity index 78% rename from fs/memware/mkdirall.go rename to pkging/memware/mkdirall.go index e426800..a3efc18 100644 --- a/fs/memware/mkdirall.go +++ b/pkging/memware/mkdirall.go @@ -5,7 +5,7 @@ import ( "path/filepath" "time" - "github.com/markbates/pkger/fs" + "github.com/markbates/pkger/pkging" ) func (fx *Warehouse) MkdirAll(p string, perm os.FileMode) error { @@ -20,7 +20,7 @@ func (fx *Warehouse) MkdirAll(p string, perm os.FileMode) error { return err } for root != "" { - pt := fs.Path{ + pt := pkging.Path{ Pkg: path.Pkg, Name: root, } @@ -32,14 +32,14 @@ func (fx *Warehouse) MkdirAll(p string, perm os.FileMode) error { continue } f := &File{ - fs: fx, - path: pt, - her: cur, - info: &fs.FileInfo{ - Details: fs.Details{ + pkging: fx, + path: pt, + her: cur, + info: &pkging.FileInfo{ + Details: pkging.Details{ Name: pt.Name, Mode: perm, - ModTime: fs.ModTime(time.Now()), + ModTime: pkging.ModTime(time.Now()), }, }, } diff --git a/fs/memware/mkdirall_test.go b/pkging/memware/mkdirall_test.go similarity index 100% rename from fs/memware/mkdirall_test.go rename to pkging/memware/mkdirall_test.go diff --git a/fs/memware/open.go b/pkging/memware/open.go similarity index 59% rename from fs/memware/open.go rename to pkging/memware/open.go index d4e5a7e..62ff730 100644 --- a/fs/memware/open.go +++ b/pkging/memware/open.go @@ -3,10 +3,10 @@ package memware import ( "fmt" - "github.com/markbates/pkger/fs" + "github.com/markbates/pkger/pkging" ) -func (fx *Warehouse) Open(name string) (fs.File, error) { +func (fx *Warehouse) Open(name string) (pkging.File, error) { pt, err := fx.Parse(name) if err != nil { return nil, err @@ -21,11 +21,11 @@ func (fx *Warehouse) Open(name string) (fs.File, error) { return nil, fmt.Errorf("could not open %s", name) } nf := &File{ - fs: fx, - info: fs.WithName(f.info.Name(), f.info), - path: f.path, - data: f.data, - her: f.her, + pkging: fx, + info: pkging.WithName(f.info.Name(), f.info), + path: f.path, + data: f.data, + her: f.her, } return nf, nil diff --git a/fs/memware/open_test.go b/pkging/memware/open_test.go similarity index 100% rename from fs/memware/open_test.go rename to pkging/memware/open_test.go diff --git a/fs/memware/stat.go b/pkging/memware/stat.go similarity index 100% rename from fs/memware/stat.go rename to pkging/memware/stat.go diff --git a/fs/memware/stat_test.go b/pkging/memware/stat_test.go similarity index 100% rename from fs/memware/stat_test.go rename to pkging/memware/stat_test.go diff --git a/fs/memware/walk.go b/pkging/memware/walk.go similarity index 83% rename from fs/memware/walk.go rename to pkging/memware/walk.go index 2836ff6..577fb48 100644 --- a/fs/memware/walk.go +++ b/pkging/memware/walk.go @@ -5,7 +5,7 @@ import ( "path/filepath" "strings" - "github.com/markbates/pkger/fs" + "github.com/markbates/pkger/pkging" ) func (f *Warehouse) Walk(p string, wf filepath.WalkFunc) error { @@ -28,7 +28,7 @@ func (f *Warehouse) Walk(p string, wf filepath.WalkFunc) error { return err } - fi = fs.WithName(strings.TrimPrefix(k.Name, pt.Name), fi) + fi = pkging.WithName(strings.TrimPrefix(k.Name, pt.Name), fi) err = wf(k.String(), fi, nil) if err != nil { return err diff --git a/fs/memware/walk_test.go b/pkging/memware/walk_test.go similarity index 100% rename from fs/memware/walk_test.go rename to pkging/memware/walk_test.go diff --git a/fs/memware/warehouse.go b/pkging/memware/warehouse.go similarity index 91% rename from fs/memware/warehouse.go rename to pkging/memware/warehouse.go index 6b59a52..1a66846 100644 --- a/fs/memware/warehouse.go +++ b/pkging/memware/warehouse.go @@ -6,12 +6,12 @@ import ( "os" "strings" - "github.com/markbates/pkger/fs" "github.com/markbates/pkger/here" "github.com/markbates/pkger/internal/maps" + "github.com/markbates/pkger/pkging" ) -var _ fs.Warehouse = &Warehouse{} +var _ pkging.Warehouse = &Warehouse{} func WithInfo(fx *Warehouse, infos ...here.Info) { for _, info := range infos { @@ -46,7 +46,7 @@ func (f *Warehouse) Abs(p string) (string, error) { return f.AbsPath(pt) } -func (f *Warehouse) AbsPath(pt fs.Path) (string, error) { +func (f *Warehouse) AbsPath(pt pkging.Path) (string, error) { return pt.String(), nil } @@ -63,7 +63,7 @@ func (f *Warehouse) Info(p string) (here.Info, error) { return info, nil } -func (f *Warehouse) Parse(p string) (fs.Path, error) { +func (f *Warehouse) Parse(p string) (pkging.Path, error) { return f.paths.Parse(p) } diff --git a/fs/memware/warehouse_test.go b/pkging/memware/warehouse_test.go similarity index 66% rename from fs/memware/warehouse_test.go rename to pkging/memware/warehouse_test.go index 2184752..9df9440 100644 --- a/fs/memware/warehouse_test.go +++ b/pkging/memware/warehouse_test.go @@ -3,8 +3,8 @@ package memware import ( "testing" - "github.com/markbates/pkger/fs/fstest" "github.com/markbates/pkger/here" + "github.com/markbates/pkger/pkging/waretest" "github.com/stretchr/testify/require" ) @@ -15,12 +15,12 @@ func Test_Warehouse(t *testing.T) { r.NoError(err) r.NotZero(info) - myfs, err := New(info) + mypkging, err := New(info) r.NoError(err) - WithInfo(myfs, info) + WithInfo(mypkging, info) - suite, err := fstest.NewSuite(myfs) + suite, err := waretest.NewSuite(mypkging) r.NoError(err) suite.Test(t) diff --git a/fs/mod_time.go b/pkging/mod_time.go similarity index 96% rename from fs/mod_time.go rename to pkging/mod_time.go index b715106..d81a32c 100644 --- a/fs/mod_time.go +++ b/pkging/mod_time.go @@ -1,4 +1,4 @@ -package fs +package pkging import ( "encoding/json" diff --git a/fs/osware/file.go b/pkging/osware/file.go similarity index 69% rename from fs/osware/file.go rename to pkging/osware/file.go index fba1713..cbc335e 100644 --- a/fs/osware/file.go +++ b/pkging/osware/file.go @@ -4,21 +4,21 @@ import ( "net/http" "os" - "github.com/markbates/pkger/fs" "github.com/markbates/pkger/here" + "github.com/markbates/pkger/pkging" ) -var _ fs.File = &File{} +var _ pkging.File = &File{} type File struct { *os.File - info *fs.FileInfo - her here.Info - path fs.Path - fs fs.Warehouse + info *pkging.FileInfo + her here.Info + path pkging.Path + pkging pkging.Warehouse } -func NewFile(fx fs.Warehouse, osf *os.File) (*File, error) { +func NewFile(fx pkging.Warehouse, osf *os.File) (*File, error) { pt, err := fx.Parse(osf.Name()) if err != nil { @@ -31,11 +31,11 @@ func NewFile(fx fs.Warehouse, osf *os.File) (*File, error) { } f := &File{ - File: osf, - path: pt, - fs: fx, + File: osf, + path: pt, + pkging: fx, } - f.info = fs.WithName(pt.Name, info) + f.info = pkging.WithName(pt.Name, info) her, err := here.Package(pt.Pkg) if err != nil { @@ -50,7 +50,7 @@ func (f *File) Close() error { } func (f *File) Abs() (string, error) { - return f.fs.AbsPath(f.path) + return f.pkging.AbsPath(f.path) } func (f *File) Info() here.Info { @@ -65,7 +65,7 @@ func (f *File) Open(name string) (http.File, error) { return f.File, nil } -func (f *File) Path() fs.Path { +func (f *File) Path() pkging.Path { return f.path } @@ -83,6 +83,6 @@ func (f *File) Stat() (os.FileInfo, error) { if err != nil { return nil, err } - f.info = fs.NewFileInfo(info) + f.info = pkging.NewFileInfo(info) return info, nil } diff --git a/fs/osware/warehouse.go b/pkging/osware/warehouse.go similarity index 86% rename from fs/osware/warehouse.go rename to pkging/osware/warehouse.go index b16f21a..f0e75f4 100644 --- a/fs/osware/warehouse.go +++ b/pkging/osware/warehouse.go @@ -7,12 +7,12 @@ import ( "path/filepath" "strings" - "github.com/markbates/pkger/fs" "github.com/markbates/pkger/here" "github.com/markbates/pkger/internal/maps" + "github.com/markbates/pkger/pkging" ) -var _ fs.Warehouse = &Warehouse{} +var _ pkging.Warehouse = &Warehouse{} type Warehouse struct { infos *maps.Infos @@ -28,7 +28,7 @@ func (f *Warehouse) Abs(p string) (string, error) { return f.AbsPath(pt) } -func (f *Warehouse) AbsPath(pt fs.Path) (string, error) { +func (f *Warehouse) AbsPath(pt pkging.Path) (string, error) { if pt.Pkg == f.current.ImportPath { return filepath.Join(f.current.Dir, pt.Name), nil } @@ -53,7 +53,7 @@ func New() (*Warehouse, error) { }, nil } -func (fx *Warehouse) Create(name string) (fs.File, error) { +func (fx *Warehouse) Create(name string) (pkging.File, error) { name, err := fx.Abs(name) if err != nil { return nil, err @@ -94,7 +94,7 @@ func (f *Warehouse) MkdirAll(p string, perm os.FileMode) error { return os.MkdirAll(p, perm) } -func (fx *Warehouse) Open(name string) (fs.File, error) { +func (fx *Warehouse) Open(name string) (pkging.File, error) { name, err := fx.Abs(name) if err != nil { return nil, err @@ -106,7 +106,7 @@ func (fx *Warehouse) Open(name string) (fs.File, error) { return NewFile(fx, f) } -func (f *Warehouse) Parse(p string) (fs.Path, error) { +func (f *Warehouse) Parse(p string) (pkging.Path, error) { return f.paths.Parse(p) } @@ -134,7 +134,7 @@ func (f *Warehouse) Stat(name string) (os.FileInfo, error) { return nil, err } - info = fs.WithName(pt.Name, fs.NewFileInfo(info)) + info = pkging.WithName(pt.Name, pkging.NewFileInfo(info)) return info, nil } @@ -159,7 +159,7 @@ func (f *Warehouse) Walk(p string, wf filepath.WalkFunc) error { if err != nil { return err } - return wf(pt.String(), fs.WithName(path, fs.NewFileInfo(fi)), nil) + return wf(pt.String(), pkging.WithName(path, pkging.NewFileInfo(fi)), nil) }) return err diff --git a/pkging/osware/warehouse_test.go b/pkging/osware/warehouse_test.go new file mode 100644 index 0000000..44324db --- /dev/null +++ b/pkging/osware/warehouse_test.go @@ -0,0 +1,24 @@ +package hdware + +import ( + "path/filepath" + "testing" + + "github.com/markbates/pkger/pkging/waretest" + "github.com/stretchr/testify/require" +) + +func Test_Warehouse(t *testing.T) { + r := require.New(t) + + mypkging, err := New() + r.NoError(err) + + mypkging.current.Dir = filepath.Join(mypkging.current.Dir, ".waretest") + mypkging.paths.Current = mypkging.current + + suite, err := waretest.NewSuite(mypkging) + r.NoError(err) + + suite.Test(t) +} diff --git a/fs/path.go b/pkging/path.go similarity index 97% rename from fs/path.go rename to pkging/path.go index 902c31e..f09061c 100644 --- a/fs/path.go +++ b/pkging/path.go @@ -1,4 +1,4 @@ -package fs +package pkging import ( "encoding/json" diff --git a/fs/warehouse.go b/pkging/warehouse.go similarity index 99% rename from fs/warehouse.go rename to pkging/warehouse.go index 596b8d7..63a63e9 100644 --- a/fs/warehouse.go +++ b/pkging/warehouse.go @@ -1,4 +1,4 @@ -package fs +package pkging import ( "os" diff --git a/pkging/waretest/file.go b/pkging/waretest/file.go new file mode 100644 index 0000000..9bddf94 --- /dev/null +++ b/pkging/waretest/file.go @@ -0,0 +1,12 @@ +package waretest + +import ( + "github.com/markbates/pkger/pkging" +) + +type TestFile struct { + Name string + Path pkging.Path +} + +type TestFiles map[pkging.Path]TestFile diff --git a/fs/fstest/fstest.go b/pkging/waretest/fstest.go similarity index 77% rename from fs/fstest/fstest.go rename to pkging/waretest/fstest.go index 581f6b1..1aacef7 100644 --- a/fs/fstest/fstest.go +++ b/pkging/waretest/fstest.go @@ -1,10 +1,10 @@ -package fstest +package waretest import ( - "github.com/markbates/pkger/fs" + "github.com/markbates/pkger/pkging" ) -func Files(fx fs.Warehouse) (TestFiles, error) { +func Files(fx pkging.Warehouse) (TestFiles, error) { tf := TestFiles{} for _, f := range fileList { pt, err := fx.Parse(f) diff --git a/fs/fstest/suite.go b/pkging/waretest/suite.go similarity index 85% rename from fs/fstest/suite.go rename to pkging/waretest/suite.go index 5d64d95..ce26134 100644 --- a/fs/fstest/suite.go +++ b/pkging/waretest/suite.go @@ -1,4 +1,4 @@ -package fstest +package waretest import ( "fmt" @@ -9,7 +9,7 @@ import ( "strings" "testing" - "github.com/markbates/pkger/fs" + "github.com/markbates/pkger/pkging" "github.com/stretchr/testify/require" ) @@ -18,12 +18,12 @@ const hart = "/easy/listening/grant.hart" const husker = "github.com/husker/du" type Suite struct { - fs.Warehouse + pkging.Warehouse } -func NewSuite(yourfs fs.Warehouse) (Suite, error) { +func NewSuite(yourpkging pkging.Warehouse) (Suite, error) { suite := Suite{ - Warehouse: yourfs, + Warehouse: yourpkging, } return suite, nil } @@ -141,17 +141,17 @@ func (s Suite) Test_Parse(t *testing.T) { ip := cur.ImportPath table := []struct { in string - exp fs.Path + exp pkging.Path }{ - {in: mould, exp: fs.Path{Pkg: ip, Name: mould}}, - {in: filepath.Join(cur.Dir, mould), exp: fs.Path{Pkg: ip, Name: mould}}, - {in: ":" + mould, exp: fs.Path{Pkg: ip, Name: mould}}, - {in: ip + ":" + mould, exp: fs.Path{Pkg: ip, Name: mould}}, - {in: ip, exp: fs.Path{Pkg: ip, Name: "/"}}, - {in: ":", exp: fs.Path{Pkg: ip, Name: "/"}}, - {in: husker + ":" + mould, exp: fs.Path{Pkg: husker, Name: mould}}, - {in: husker, exp: fs.Path{Pkg: husker, Name: "/"}}, - {in: husker + ":", exp: fs.Path{Pkg: husker, Name: "/"}}, + {in: mould, exp: pkging.Path{Pkg: ip, Name: mould}}, + {in: filepath.Join(cur.Dir, mould), exp: pkging.Path{Pkg: ip, Name: mould}}, + {in: ":" + mould, exp: pkging.Path{Pkg: ip, Name: mould}}, + {in: ip + ":" + mould, exp: pkging.Path{Pkg: ip, Name: mould}}, + {in: ip, exp: pkging.Path{Pkg: ip, Name: "/"}}, + {in: ":", exp: pkging.Path{Pkg: ip, Name: "/"}}, + {in: husker + ":" + mould, exp: pkging.Path{Pkg: husker, Name: mould}}, + {in: husker, exp: pkging.Path{Pkg: husker, Name: "/"}}, + {in: husker + ":", exp: pkging.Path{Pkg: husker, Name: "/"}}, } for _, tt := range table { From f83c92f3e96368b7d030f8371e535c522c71c9ec Mon Sep 17 00:00:00 2001 From: Mark Bates Date: Sun, 1 Sep 2019 18:05:54 -0400 Subject: [PATCH 23/46] somebody take me --- pkging/memware/warehouse_test.go | 6 +++--- pkging/waretest/file.go | 12 ------------ pkging/waretest/fstest.go | 31 ------------------------------- pkging/waretest/waretest.go | 1 + 4 files changed, 4 insertions(+), 46 deletions(-) delete mode 100644 pkging/waretest/file.go delete mode 100644 pkging/waretest/fstest.go create mode 100644 pkging/waretest/waretest.go diff --git a/pkging/memware/warehouse_test.go b/pkging/memware/warehouse_test.go index 9df9440..9eb1032 100644 --- a/pkging/memware/warehouse_test.go +++ b/pkging/memware/warehouse_test.go @@ -15,12 +15,12 @@ func Test_Warehouse(t *testing.T) { r.NoError(err) r.NotZero(info) - mypkging, err := New(info) + wh, err := New(info) r.NoError(err) - WithInfo(mypkging, info) + WithInfo(wh, info) - suite, err := waretest.NewSuite(mypkging) + suite, err := waretest.NewSuite(wh) r.NoError(err) suite.Test(t) diff --git a/pkging/waretest/file.go b/pkging/waretest/file.go deleted file mode 100644 index 9bddf94..0000000 --- a/pkging/waretest/file.go +++ /dev/null @@ -1,12 +0,0 @@ -package waretest - -import ( - "github.com/markbates/pkger/pkging" -) - -type TestFile struct { - Name string - Path pkging.Path -} - -type TestFiles map[pkging.Path]TestFile diff --git a/pkging/waretest/fstest.go b/pkging/waretest/fstest.go deleted file mode 100644 index 1aacef7..0000000 --- a/pkging/waretest/fstest.go +++ /dev/null @@ -1,31 +0,0 @@ -package waretest - -import ( - "github.com/markbates/pkger/pkging" -) - -func Files(fx pkging.Warehouse) (TestFiles, error) { - tf := TestFiles{} - for _, f := range fileList { - pt, err := fx.Parse(f) - if err != nil { - return tf, err - } - tf[pt] = TestFile{ - Name: pt.Name, - Path: pt, - } - } - - return tf, nil -} - -var fileList = []string{ - "/main.go", - "/go.mod", - "/go.sum", - "/public/index.html", - "/public/images/mark.png", - "/templates/a.txt", - "/templates/b/b.txt", -} diff --git a/pkging/waretest/waretest.go b/pkging/waretest/waretest.go new file mode 100644 index 0000000..92b37c8 --- /dev/null +++ b/pkging/waretest/waretest.go @@ -0,0 +1 @@ +package waretest From 1c5d8bddb0040748a8419a2dc3023fcc989dc8bb Mon Sep 17 00:00:00 2001 From: Mark Bates Date: Sun, 1 Sep 2019 22:07:52 -0400 Subject: [PATCH 24/46] gonna be the one for you --- pkging/waretest/suite.go | 49 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 2 deletions(-) diff --git a/pkging/waretest/suite.go b/pkging/waretest/suite.go index ce26134..48f9c87 100644 --- a/pkging/waretest/suite.go +++ b/pkging/waretest/suite.go @@ -3,6 +3,7 @@ package waretest import ( "fmt" "io" + "io/ioutil" "os" "path/filepath" "reflect" @@ -128,8 +129,52 @@ func (s Suite) Test_MkdirAll(t *testing.T) { panic("not implemented") } -func (s Suite) Test_Open(t *testing.T) { - panic("not implemented") +func (s Suite) Test_Open_File(t *testing.T) { + r := require.New(t) + + cur, err := s.Current() + r.NoError(err) + + ip := cur.ImportPath + table := []struct { + in string + }{ + {in: mould}, + {in: ":" + mould}, + {in: ip + ":" + mould}, + {in: hart}, + } + + for _, tt := range table { + t.Run(tt.in, func(st *testing.T) { + + r := require.New(st) + + pt, err := s.Parse(tt.in) + r.NoError(err) + + r.NoError(s.RemoveAll(pt.String())) + + body := "!" + pt.String() + + f1, err := s.Create(tt.in) + r.NoError(err) + + _, err = io.Copy(f1, strings.NewReader(body)) + r.NoError(err) + r.NoError(f1.Close()) + + f2, err := s.Open(tt.in) + r.NoError(err) + + r.Equal(pt.Name, f2.Path().Name) + b, err := ioutil.ReadAll(f2) + r.NoError(err) + r.Equal(body, string(b)) + + r.NoError(f2.Close()) + }) + } } func (s Suite) Test_Parse(t *testing.T) { From c9705411800bb2c85642e60062edd8dcbd060ebe Mon Sep 17 00:00:00 2001 From: Mark Bates Date: Sun, 1 Sep 2019 22:20:02 -0400 Subject: [PATCH 25/46] i will wait --- pkging/memware/create.go | 5 ---- pkging/osware/warehouse.go | 3 --- pkging/waretest/suite.go | 48 +++++++++++++++++++++++++++++--------- 3 files changed, 37 insertions(+), 19 deletions(-) diff --git a/pkging/memware/create.go b/pkging/memware/create.go index eccef75..c4b2d9c 100644 --- a/pkging/memware/create.go +++ b/pkging/memware/create.go @@ -1,7 +1,6 @@ package memware import ( - "path/filepath" "time" "github.com/markbates/pkger/pkging" @@ -32,9 +31,5 @@ func (fx *Warehouse) Create(name string) (pkging.File, error) { fx.files.Store(pt, f) - dir := filepath.Dir(pt.Name) - if err := fx.MkdirAll(dir, 0644); err != nil { - return nil, err - } return f, nil } diff --git a/pkging/osware/warehouse.go b/pkging/osware/warehouse.go index f0e75f4..9ad054e 100644 --- a/pkging/osware/warehouse.go +++ b/pkging/osware/warehouse.go @@ -58,9 +58,6 @@ func (fx *Warehouse) Create(name string) (pkging.File, error) { if err != nil { return nil, err } - if err := fx.MkdirAll(filepath.Dir(name), 0755); err != nil { - return nil, err - } f, err := os.Create(name) if err != nil { return nil, err diff --git a/pkging/waretest/suite.go b/pkging/waretest/suite.go index 48f9c87..8bef502 100644 --- a/pkging/waretest/suite.go +++ b/pkging/waretest/suite.go @@ -88,21 +88,44 @@ func (s Suite) Clean() error { func (s Suite) Test_Create(t *testing.T) { r := require.New(t) - - pt, err := s.Parse(mould) + cur, err := s.Current() r.NoError(err) - f, err := s.Create(pt.Name) - r.NoError(err) - r.Equal(pt.Name, f.Name()) + ip := cur.ImportPath + table := []struct { + in string + }{ + {in: mould}, + {in: ":" + mould}, + {in: ip + ":" + mould}, + {in: filepath.Dir(mould)}, + {in: ":" + filepath.Dir(mould)}, + {in: ip + ":" + filepath.Dir(mould)}, + } - fi, err := f.Stat() - r.NoError(err) + for _, tt := range table { + t.Run(tt.in, func(st *testing.T) { + r := require.New(st) - r.Equal(pt.Name, fi.Name()) - r.Equal(os.FileMode(0644), fi.Mode()) - r.NotZero(fi.ModTime()) - r.NoError(s.RemoveAll(pt.String())) + pt, err := s.Parse(tt.in) + r.NoError(err) + + r.NoError(s.RemoveAll(pt.String())) + r.NoError(s.MkdirAll(filepath.Dir(pt.Name), 0755)) + + f, err := s.Create(pt.Name) + r.NoError(err) + r.Equal(pt.Name, f.Name()) + + fi, err := f.Stat() + r.NoError(err) + + r.Equal(pt.Name, fi.Name()) + r.Equal(os.FileMode(0644), fi.Mode()) + r.NotZero(fi.ModTime()) + r.NoError(s.RemoveAll(pt.String())) + }) + } } func (s Suite) Test_Current(t *testing.T) { @@ -154,6 +177,7 @@ func (s Suite) Test_Open_File(t *testing.T) { r.NoError(err) r.NoError(s.RemoveAll(pt.String())) + r.NoError(s.MkdirAll(filepath.Dir(pt.Name), 0755)) body := "!" + pt.String() @@ -309,9 +333,11 @@ func (s Suite) Test_Stat_File(t *testing.T) { r.NoError(err) r.NoError(s.RemoveAll(pt.String())) + r.NoError(s.MkdirAll(filepath.Dir(pt.Name), 0755)) f, err := s.Create(tt.in) r.NoError(err) + _, err = io.Copy(f, strings.NewReader("!"+pt.String())) r.NoError(err) r.NoError(f.Close()) From 9d7d315d44d25d6b52715d6d087e4cae365050a5 Mon Sep 17 00:00:00 2001 From: Mark Bates Date: Sun, 1 Sep 2019 22:25:53 -0400 Subject: [PATCH 26/46] paid to smile --- pkging/memware/create.go | 6 ++++++ pkging/waretest/suite.go | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/pkging/memware/create.go b/pkging/memware/create.go index c4b2d9c..4d7d9f3 100644 --- a/pkging/memware/create.go +++ b/pkging/memware/create.go @@ -1,11 +1,13 @@ package memware import ( + "path/filepath" "time" "github.com/markbates/pkger/pkging" ) +// no such file or directory func (fx *Warehouse) Create(name string) (pkging.File, error) { pt, err := fx.Parse(name) if err != nil { @@ -16,6 +18,10 @@ func (fx *Warehouse) Create(name string) (pkging.File, error) { if err != nil { return nil, err } + + if _, err := fx.Stat(filepath.Dir(pt.Name)); err != nil { + return nil, err + } f := &File{ path: pt, her: her, diff --git a/pkging/waretest/suite.go b/pkging/waretest/suite.go index 8bef502..e760a98 100644 --- a/pkging/waretest/suite.go +++ b/pkging/waretest/suite.go @@ -128,6 +128,38 @@ func (s Suite) Test_Create(t *testing.T) { } } +func (s Suite) Test_Create_No_MkdirAll(t *testing.T) { + r := require.New(t) + cur, err := s.Current() + r.NoError(err) + + ip := cur.ImportPath + table := []struct { + in string + }{ + {in: mould}, + {in: ":" + mould}, + {in: ip + ":" + mould}, + {in: filepath.Dir(mould)}, + {in: ":" + filepath.Dir(mould)}, + {in: ip + ":" + filepath.Dir(mould)}, + } + + for _, tt := range table { + t.Run(tt.in, func(st *testing.T) { + r := require.New(st) + + pt, err := s.Parse(tt.in) + r.NoError(err) + + r.NoError(s.RemoveAll(pt.String())) + + _, err = s.Create(pt.Name) + r.Error(err) + }) + } +} + func (s Suite) Test_Current(t *testing.T) { r := require.New(t) From 5d76c9af09418246238e593151fc57f38f17b766 Mon Sep 17 00:00:00 2001 From: Mark Bates Date: Mon, 2 Sep 2019 12:55:26 -0400 Subject: [PATCH 27/46] i'll sing about you if nobody else will --- pkging/memware/create.go | 1 + pkging/waretest/suite.go | 38 +++++++++++++++++++++++++++++++++++++- 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/pkging/memware/create.go b/pkging/memware/create.go index 4d7d9f3..b9a34ee 100644 --- a/pkging/memware/create.go +++ b/pkging/memware/create.go @@ -22,6 +22,7 @@ func (fx *Warehouse) Create(name string) (pkging.File, error) { if _, err := fx.Stat(filepath.Dir(pt.Name)); err != nil { return nil, err } + f := &File{ path: pt, her: her, diff --git a/pkging/waretest/suite.go b/pkging/waretest/suite.go index e760a98..c8b4e52 100644 --- a/pkging/waretest/suite.go +++ b/pkging/waretest/suite.go @@ -181,7 +181,43 @@ func (s Suite) Test_Info(t *testing.T) { } func (s Suite) Test_MkdirAll(t *testing.T) { - panic("not implemented") + r := require.New(t) + cur, err := s.Current() + r.NoError(err) + + ip := cur.ImportPath + table := []struct { + in string + }{ + {in: mould}, + {in: ":" + mould}, + {in: ip + ":" + mould}, + {in: filepath.Dir(mould)}, + {in: ":" + filepath.Dir(mould)}, + {in: ip + ":" + filepath.Dir(mould)}, + } + + for _, tt := range table { + t.Run(tt.in, func(st *testing.T) { + r := require.New(st) + + pt, err := s.Parse(tt.in) + r.NoError(err) + + r.NoError(s.RemoveAll(pt.String())) + + dir := filepath.Dir(pt.Name) + r.NoError(s.MkdirAll(dir, 0755)) + + fi, err := s.Stat(dir) + r.NoError(err) + + r.Equal(dir, fi.Name()) + r.Equal(os.FileMode(0755), fi.Mode().Perm()) + r.NotZero(fi.ModTime()) + r.NoError(s.RemoveAll(pt.String())) + }) + } } func (s Suite) Test_Open_File(t *testing.T) { From c3ae1d1bda4c91241357f27d38473de645379cc3 Mon Sep 17 00:00:00 2001 From: Mark Bates Date: Mon, 2 Sep 2019 12:57:18 -0400 Subject: [PATCH 28/46] humble daisy --- pkging/waretest/suite.go | 46 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 42 insertions(+), 4 deletions(-) diff --git a/pkging/waretest/suite.go b/pkging/waretest/suite.go index c8b4e52..2ee141c 100644 --- a/pkging/waretest/suite.go +++ b/pkging/waretest/suite.go @@ -302,10 +302,6 @@ func (s Suite) Test_Parse(t *testing.T) { } } -func (s Suite) Test_ReadFile(t *testing.T) { - panic("not implemented") -} - func (s Suite) Test_Stat_Error(t *testing.T) { r := require.New(t) @@ -420,3 +416,45 @@ func (s Suite) Test_Stat_File(t *testing.T) { func (s Suite) Test_Walk(t *testing.T) { panic("not implemented") } + +func (s Suite) Test_ReadFile(t *testing.T) { + r := require.New(t) + + cur, err := s.Current() + r.NoError(err) + + ip := cur.ImportPath + table := []struct { + in string + }{ + {in: mould}, + {in: ":" + mould}, + {in: ip + ":" + mould}, + {in: hart}, + } + + for _, tt := range table { + t.Run(tt.in, func(st *testing.T) { + + r := require.New(st) + + pt, err := s.Parse(tt.in) + r.NoError(err) + + r.NoError(s.RemoveAll(pt.String())) + r.NoError(s.MkdirAll(filepath.Dir(pt.Name), 0755)) + + f, err := s.Create(tt.in) + r.NoError(err) + + body := "!" + pt.String() + _, err = io.Copy(f, strings.NewReader(body)) + r.NoError(err) + r.NoError(f.Close()) + + b, err := s.ReadFile(tt.in) + r.NoError(err) + r.Equal(body, string(b)) + }) + } +} From b6440c5fec88415645152ffc6895137eaa6bde6d Mon Sep 17 00:00:00 2001 From: Mark Bates Date: Tue, 3 Sep 2019 11:29:28 -0400 Subject: [PATCH 29/46] dancing in the dark --- pkging/{memware => mem}/create.go | 4 +-- pkging/{memware => mem}/create_test.go | 2 +- pkging/{memware => mem}/file.go | 4 +-- pkging/{memware => mem}/file_test.go | 2 +- pkging/mem/http.go | 1 + pkging/{memware => mem}/http_test.go | 8 ++--- pkging/{memware => mem}/json.go | 2 +- pkging/{memware => mem}/json_test.go | 2 +- pkging/{memware/warehouse.go => mem/mem.go} | 36 +++++++------------ .../warehouse_test.go => mem/mem_test.go} | 8 ++--- pkging/{memware => mem}/mkdirall.go | 4 +-- pkging/{memware => mem}/mkdirall_test.go | 2 +- pkging/{memware => mem}/open.go | 4 +-- pkging/{memware => mem}/open_test.go | 2 +- pkging/{memware => mem}/stat.go | 4 +-- pkging/{memware => mem}/stat_test.go | 2 +- pkging/{memware => mem}/walk.go | 4 +-- pkging/{memware => mem}/walk_test.go | 2 +- pkging/memware/http.go | 1 - pkging/{warehouse.go => pkger.go} | 5 +-- pkging/{waretest => pkgtest}/suite.go | 25 +++++++++---- pkging/pkgutil/file.go | 17 +++++++++ pkging/{osware => stdos}/file.go | 6 ++-- .../{osware/warehouse.go => stdos/stdos.go} | 36 +++++++++---------- .../warehouse_test.go => stdos/stdos_test.go} | 10 +++--- pkging/waretest/waretest.go | 1 - 26 files changed, 105 insertions(+), 89 deletions(-) rename pkging/{memware => mem}/create.go (87%) rename pkging/{memware => mem}/create_test.go (99%) rename pkging/{memware => mem}/file.go (98%) rename pkging/{memware => mem}/file_test.go (98%) create mode 100644 pkging/mem/http.go rename pkging/{memware => mem}/http_test.go (95%) rename pkging/{memware => mem}/json.go (98%) rename pkging/{memware => mem}/json_test.go (97%) rename pkging/{memware/warehouse.go => mem/mem.go} (66%) rename pkging/{memware/warehouse_test.go => mem/mem_test.go} (67%) rename pkging/{memware => mem}/mkdirall.go (91%) rename pkging/{memware => mem}/mkdirall_test.go (96%) rename pkging/{memware => mem}/open.go (85%) rename pkging/{memware => mem}/open_test.go (96%) rename pkging/{memware => mem}/stat.go (71%) rename pkging/{memware => mem}/stat_test.go (95%) rename pkging/{memware => mem}/walk.go (87%) rename pkging/{memware => mem}/walk_test.go (98%) delete mode 100644 pkging/memware/http.go rename pkging/{warehouse.go => pkger.go} (87%) rename pkging/{waretest => pkgtest}/suite.go (94%) create mode 100644 pkging/pkgutil/file.go rename pkging/{osware => stdos}/file.go (92%) rename pkging/{osware/warehouse.go => stdos/stdos.go} (72%) rename pkging/{osware/warehouse_test.go => stdos/stdos_test.go} (51%) delete mode 100644 pkging/waretest/waretest.go diff --git a/pkging/memware/create.go b/pkging/mem/create.go similarity index 87% rename from pkging/memware/create.go rename to pkging/mem/create.go index b9a34ee..d8ae1ca 100644 --- a/pkging/memware/create.go +++ b/pkging/mem/create.go @@ -1,4 +1,4 @@ -package memware +package mem import ( "path/filepath" @@ -8,7 +8,7 @@ import ( ) // no such file or directory -func (fx *Warehouse) Create(name string) (pkging.File, error) { +func (fx *Pkger) Create(name string) (pkging.File, error) { pt, err := fx.Parse(name) if err != nil { return nil, err diff --git a/pkging/memware/create_test.go b/pkging/mem/create_test.go similarity index 99% rename from pkging/memware/create_test.go rename to pkging/mem/create_test.go index bcab262..ed92d10 100644 --- a/pkging/memware/create_test.go +++ b/pkging/mem/create_test.go @@ -1,4 +1,4 @@ -package memware +package mem // func Test_Create(t *testing.T) { // r := require.New(t) diff --git a/pkging/memware/file.go b/pkging/mem/file.go similarity index 98% rename from pkging/memware/file.go rename to pkging/mem/file.go index b5b89f5..6f32073 100644 --- a/pkging/memware/file.go +++ b/pkging/mem/file.go @@ -1,4 +1,4 @@ -package memware +package mem import ( "bytes" @@ -27,7 +27,7 @@ type File struct { parent pkging.Path writer *bytes.Buffer reader io.Reader - pkging pkging.Warehouse + pkging pkging.Pkger } func (f *File) Seek(ofpkginget int64, whence int) (int64, error) { diff --git a/pkging/memware/file_test.go b/pkging/mem/file_test.go similarity index 98% rename from pkging/memware/file_test.go rename to pkging/mem/file_test.go index 87c636f..2903001 100644 --- a/pkging/memware/file_test.go +++ b/pkging/mem/file_test.go @@ -1,4 +1,4 @@ -package memware +package mem // func Test_File_Read_Memory(t *testing.T) { // r := require.New(t) diff --git a/pkging/mem/http.go b/pkging/mem/http.go new file mode 100644 index 0000000..6a9fb31 --- /dev/null +++ b/pkging/mem/http.go @@ -0,0 +1 @@ +package mem diff --git a/pkging/memware/http_test.go b/pkging/mem/http_test.go similarity index 95% rename from pkging/memware/http_test.go rename to pkging/mem/http_test.go index a075de8..6719aa1 100644 --- a/pkging/memware/http_test.go +++ b/pkging/mem/http_test.go @@ -1,9 +1,9 @@ -package memware +package mem // func Test_HTTP_Dir(t *testing.T) { // r := require.New(t) // -// fs := NewWarehouse() +// fs := NewPkger() // // r.NoError(Folder.Create(fs)) // @@ -24,7 +24,7 @@ package memware // func Test_HTTP_File_Memory(t *testing.T) { // r := require.New(t) // -// fs := NewWarehouse() +// fs := NewPkger() // r.NoError(Folder.Create(fs)) // // dir, err := fs.Open("/") @@ -44,7 +44,7 @@ package memware // func Test_HTTP_Dir_Memory_StripPrefix(t *testing.T) { // r := require.New(t) // -// fs := NewWarehouse() +// fs := NewPkger() // r.NoError(Folder.Create(fs)) // // dir, err := fs.Open("/public") diff --git a/pkging/memware/json.go b/pkging/mem/json.go similarity index 98% rename from pkging/memware/json.go rename to pkging/mem/json.go index 717d830..55a626b 100644 --- a/pkging/memware/json.go +++ b/pkging/mem/json.go @@ -1,4 +1,4 @@ -package memware +package mem import ( "encoding/json" diff --git a/pkging/memware/json_test.go b/pkging/mem/json_test.go similarity index 97% rename from pkging/memware/json_test.go rename to pkging/mem/json_test.go index 585f109..f258cf4 100644 --- a/pkging/memware/json_test.go +++ b/pkging/mem/json_test.go @@ -1,4 +1,4 @@ -package memware +package mem // func Test_File_JSON(t *testing.T) { // r := require.New(t) diff --git a/pkging/memware/warehouse.go b/pkging/mem/mem.go similarity index 66% rename from pkging/memware/warehouse.go rename to pkging/mem/mem.go index 1a66846..d0bf18c 100644 --- a/pkging/memware/warehouse.go +++ b/pkging/mem/mem.go @@ -1,8 +1,7 @@ -package memware +package mem import ( "fmt" - "io/ioutil" "os" "strings" @@ -11,16 +10,16 @@ import ( "github.com/markbates/pkger/pkging" ) -var _ pkging.Warehouse = &Warehouse{} +var _ pkging.Pkger = &Pkger{} -func WithInfo(fx *Warehouse, infos ...here.Info) { +func WithInfo(fx *Pkger, infos ...here.Info) { for _, info := range infos { fx.infos.Store(info.ImportPath, info) } } -func New(info here.Info) (*Warehouse, error) { - f := &Warehouse{ +func New(info here.Info) (*Pkger, error) { + f := &Pkger{ infos: &maps.Infos{}, paths: &maps.Paths{ Current: info, @@ -31,14 +30,14 @@ func New(info here.Info) (*Warehouse, error) { return f, nil } -type Warehouse struct { +type Pkger struct { infos *maps.Infos paths *maps.Paths files *maps.Files current here.Info } -func (f *Warehouse) Abs(p string) (string, error) { +func (f *Pkger) Abs(p string) (string, error) { pt, err := f.Parse(p) if err != nil { return "", err @@ -46,15 +45,15 @@ func (f *Warehouse) Abs(p string) (string, error) { return f.AbsPath(pt) } -func (f *Warehouse) AbsPath(pt pkging.Path) (string, error) { +func (f *Pkger) AbsPath(pt pkging.Path) (string, error) { return pt.String(), nil } -func (f *Warehouse) Current() (here.Info, error) { +func (f *Pkger) Current() (here.Info, error) { return f.current, nil } -func (f *Warehouse) Info(p string) (here.Info, error) { +func (f *Pkger) Info(p string) (here.Info, error) { info, ok := f.infos.Load(p) if !ok { return info, fmt.Errorf("no such package %q", p) @@ -63,20 +62,11 @@ func (f *Warehouse) Info(p string) (here.Info, error) { return info, nil } -func (f *Warehouse) Parse(p string) (pkging.Path, error) { +func (f *Pkger) Parse(p string) (pkging.Path, error) { return f.paths.Parse(p) } -func (fx *Warehouse) ReadFile(s string) ([]byte, error) { - f, err := fx.Open(s) - if err != nil { - return nil, err - } - defer f.Close() - return ioutil.ReadAll(f) -} - -func (fx *Warehouse) Remove(name string) error { +func (fx *Pkger) Remove(name string) error { pt, err := fx.Parse(name) if err != nil { return err @@ -90,7 +80,7 @@ func (fx *Warehouse) Remove(name string) error { return nil } -func (fx *Warehouse) RemoveAll(name string) error { +func (fx *Pkger) RemoveAll(name string) error { pt, err := fx.Parse(name) if err != nil { return err diff --git a/pkging/memware/warehouse_test.go b/pkging/mem/mem_test.go similarity index 67% rename from pkging/memware/warehouse_test.go rename to pkging/mem/mem_test.go index 9eb1032..925b26b 100644 --- a/pkging/memware/warehouse_test.go +++ b/pkging/mem/mem_test.go @@ -1,14 +1,14 @@ -package memware +package mem import ( "testing" "github.com/markbates/pkger/here" - "github.com/markbates/pkger/pkging/waretest" + "github.com/markbates/pkger/pkging/pkgtest" "github.com/stretchr/testify/require" ) -func Test_Warehouse(t *testing.T) { +func Test_Pkger(t *testing.T) { r := require.New(t) info, err := here.Current() @@ -20,7 +20,7 @@ func Test_Warehouse(t *testing.T) { WithInfo(wh, info) - suite, err := waretest.NewSuite(wh) + suite, err := pkgtest.NewSuite(wh) r.NoError(err) suite.Test(t) diff --git a/pkging/memware/mkdirall.go b/pkging/mem/mkdirall.go similarity index 91% rename from pkging/memware/mkdirall.go rename to pkging/mem/mkdirall.go index a3efc18..eb17709 100644 --- a/pkging/memware/mkdirall.go +++ b/pkging/mem/mkdirall.go @@ -1,4 +1,4 @@ -package memware +package mem import ( "os" @@ -8,7 +8,7 @@ import ( "github.com/markbates/pkger/pkging" ) -func (fx *Warehouse) MkdirAll(p string, perm os.FileMode) error { +func (fx *Pkger) MkdirAll(p string, perm os.FileMode) error { path, err := fx.Parse(p) if err != nil { return err diff --git a/pkging/memware/mkdirall_test.go b/pkging/mem/mkdirall_test.go similarity index 96% rename from pkging/memware/mkdirall_test.go rename to pkging/mem/mkdirall_test.go index fa3f4df..d8f4299 100644 --- a/pkging/memware/mkdirall_test.go +++ b/pkging/mem/mkdirall_test.go @@ -1,4 +1,4 @@ -package memware +package mem import ( "os" diff --git a/pkging/memware/open.go b/pkging/mem/open.go similarity index 85% rename from pkging/memware/open.go rename to pkging/mem/open.go index 62ff730..cd56aac 100644 --- a/pkging/memware/open.go +++ b/pkging/mem/open.go @@ -1,4 +1,4 @@ -package memware +package mem import ( "fmt" @@ -6,7 +6,7 @@ import ( "github.com/markbates/pkger/pkging" ) -func (fx *Warehouse) Open(name string) (pkging.File, error) { +func (fx *Pkger) Open(name string) (pkging.File, error) { pt, err := fx.Parse(name) if err != nil { return nil, err diff --git a/pkging/memware/open_test.go b/pkging/mem/open_test.go similarity index 96% rename from pkging/memware/open_test.go rename to pkging/mem/open_test.go index 288fd73..dfd8651 100644 --- a/pkging/memware/open_test.go +++ b/pkging/mem/open_test.go @@ -1,4 +1,4 @@ -package memware +package mem // func Test_Open(t *testing.T) { // r := require.New(t) diff --git a/pkging/memware/stat.go b/pkging/mem/stat.go similarity index 71% rename from pkging/memware/stat.go rename to pkging/mem/stat.go index 2711a3e..1906418 100644 --- a/pkging/memware/stat.go +++ b/pkging/mem/stat.go @@ -1,11 +1,11 @@ -package memware +package mem import ( "fmt" "os" ) -func (fx *Warehouse) Stat(name string) (os.FileInfo, error) { +func (fx *Pkger) Stat(name string) (os.FileInfo, error) { pt, err := fx.Parse(name) if err != nil { return nil, err diff --git a/pkging/memware/stat_test.go b/pkging/mem/stat_test.go similarity index 95% rename from pkging/memware/stat_test.go rename to pkging/mem/stat_test.go index b4dd5c2..4a2817c 100644 --- a/pkging/memware/stat_test.go +++ b/pkging/mem/stat_test.go @@ -1,4 +1,4 @@ -package memware +package mem // func Test_Stat(t *testing.T) { // r := require.New(t) diff --git a/pkging/memware/walk.go b/pkging/mem/walk.go similarity index 87% rename from pkging/memware/walk.go rename to pkging/mem/walk.go index 577fb48..96f7421 100644 --- a/pkging/memware/walk.go +++ b/pkging/mem/walk.go @@ -1,4 +1,4 @@ -package memware +package mem import ( "fmt" @@ -8,7 +8,7 @@ import ( "github.com/markbates/pkger/pkging" ) -func (f *Warehouse) Walk(p string, wf filepath.WalkFunc) error { +func (f *Pkger) Walk(p string, wf filepath.WalkFunc) error { keys := f.files.Keys() pt, err := f.Parse(p) diff --git a/pkging/memware/walk_test.go b/pkging/mem/walk_test.go similarity index 98% rename from pkging/memware/walk_test.go rename to pkging/mem/walk_test.go index 0d45c10..e36d03f 100644 --- a/pkging/memware/walk_test.go +++ b/pkging/mem/walk_test.go @@ -1,4 +1,4 @@ -package memware +package mem // func Test_Walk(t *testing.T) { // r := require.New(t) diff --git a/pkging/memware/http.go b/pkging/memware/http.go deleted file mode 100644 index 2ed2560..0000000 --- a/pkging/memware/http.go +++ /dev/null @@ -1 +0,0 @@ -package memware diff --git a/pkging/warehouse.go b/pkging/pkger.go similarity index 87% rename from pkging/warehouse.go rename to pkging/pkger.go index 63a63e9..19757b5 100644 --- a/pkging/warehouse.go +++ b/pkging/pkger.go @@ -7,7 +7,7 @@ import ( "github.com/markbates/pkger/here" ) -type Warehouse interface { +type Pkger interface { Parse(p string) (Path, error) Abs(string) (string, error) AbsPath(Path) (string, error) @@ -15,9 +15,6 @@ type Warehouse interface { Current() (here.Info, error) Info(p string) (here.Info, error) - // ReadFile reads the file named by filename and returns the contents. A successful call returns err == nil, not err == EOF. Because ReadFile reads the whole file, it does not treat an EOF from Read as an error to be reported. - ReadFile(s string) ([]byte, error) - // Create creates the named file with mode 0666 (before umask) - It's actually 0644, truncating it if it already exists. If successful, methods on the returned File can be used for I/O; the associated file descriptor has mode O_RDWR. Create(name string) (File, error) diff --git a/pkging/waretest/suite.go b/pkging/pkgtest/suite.go similarity index 94% rename from pkging/waretest/suite.go rename to pkging/pkgtest/suite.go index 2ee141c..af4fe78 100644 --- a/pkging/waretest/suite.go +++ b/pkging/pkgtest/suite.go @@ -1,4 +1,4 @@ -package waretest +package pkgtest import ( "fmt" @@ -11,6 +11,7 @@ import ( "testing" "github.com/markbates/pkger/pkging" + "github.com/markbates/pkger/pkging/pkgutil" "github.com/stretchr/testify/require" ) @@ -19,12 +20,12 @@ const hart = "/easy/listening/grant.hart" const husker = "github.com/husker/du" type Suite struct { - pkging.Warehouse + pkging.Pkger } -func NewSuite(yourpkging pkging.Warehouse) (Suite, error) { +func NewSuite(yourpkging pkging.Pkger) (Suite, error) { suite := Suite{ - Warehouse: yourpkging, + Pkger: yourpkging, } return suite, nil } @@ -46,7 +47,7 @@ func (s Suite) Test(t *testing.T) { func (s Suite) sub(t *testing.T, m reflect.Method) { name := strings.TrimPrefix(m.Name, "Test_") - name = fmt.Sprintf("%T_%s", s.Warehouse, name) + name = fmt.Sprintf("%T_%s", s.Pkger, name) t.Run(name, func(st *testing.T) { defer func() { if err := recover(); err != nil { @@ -417,6 +418,18 @@ func (s Suite) Test_Walk(t *testing.T) { panic("not implemented") } +func (s Suite) Test_Remove(t *testing.T) { + panic("not implemented") +} + +func (s Suite) Test_HTTP_Open(t *testing.T) { + panic("not implemented") +} + +func (s Suite) Test_HTTP_Readdir(t *testing.T) { + panic("not implemented") +} + func (s Suite) Test_ReadFile(t *testing.T) { r := require.New(t) @@ -452,7 +465,7 @@ func (s Suite) Test_ReadFile(t *testing.T) { r.NoError(err) r.NoError(f.Close()) - b, err := s.ReadFile(tt.in) + b, err := pkgutil.ReadFile(s, tt.in) r.NoError(err) r.Equal(body, string(b)) }) diff --git a/pkging/pkgutil/file.go b/pkging/pkgutil/file.go new file mode 100644 index 0000000..b7505a7 --- /dev/null +++ b/pkging/pkgutil/file.go @@ -0,0 +1,17 @@ +package pkgutil + +import ( + "io/ioutil" + + "github.com/markbates/pkger/pkging" +) + +// ReadFile reads the file named by filename and returns the contents. A successful call returns err == nil, not err == EOF. Because ReadFile reads the whole file, it does not treat an EOF from Read as an error to be reported. +func ReadFile(pkg pkging.Pkger, s string) ([]byte, error) { + f, err := pkg.Open(s) + if err != nil { + return nil, err + } + defer f.Close() + return ioutil.ReadAll(f) +} diff --git a/pkging/osware/file.go b/pkging/stdos/file.go similarity index 92% rename from pkging/osware/file.go rename to pkging/stdos/file.go index cbc335e..fd64c9d 100644 --- a/pkging/osware/file.go +++ b/pkging/stdos/file.go @@ -1,4 +1,4 @@ -package hdware +package stdos import ( "net/http" @@ -15,10 +15,10 @@ type File struct { info *pkging.FileInfo her here.Info path pkging.Path - pkging pkging.Warehouse + pkging pkging.Pkger } -func NewFile(fx pkging.Warehouse, osf *os.File) (*File, error) { +func NewFile(fx pkging.Pkger, osf *os.File) (*File, error) { pt, err := fx.Parse(osf.Name()) if err != nil { diff --git a/pkging/osware/warehouse.go b/pkging/stdos/stdos.go similarity index 72% rename from pkging/osware/warehouse.go rename to pkging/stdos/stdos.go index 9ad054e..44ffa0e 100644 --- a/pkging/osware/warehouse.go +++ b/pkging/stdos/stdos.go @@ -1,4 +1,4 @@ -package hdware +package stdos import ( "fmt" @@ -12,15 +12,15 @@ import ( "github.com/markbates/pkger/pkging" ) -var _ pkging.Warehouse = &Warehouse{} +var _ pkging.Pkger = &Pkger{} -type Warehouse struct { +type Pkger struct { infos *maps.Infos paths *maps.Paths current here.Info } -func (f *Warehouse) Abs(p string) (string, error) { +func (f *Pkger) Abs(p string) (string, error) { pt, err := f.Parse(p) if err != nil { return "", err @@ -28,7 +28,7 @@ func (f *Warehouse) Abs(p string) (string, error) { return f.AbsPath(pt) } -func (f *Warehouse) AbsPath(pt pkging.Path) (string, error) { +func (f *Pkger) AbsPath(pt pkging.Path) (string, error) { if pt.Pkg == f.current.ImportPath { return filepath.Join(f.current.Dir, pt.Name), nil } @@ -39,12 +39,12 @@ func (f *Warehouse) AbsPath(pt pkging.Path) (string, error) { return filepath.Join(info.Dir, pt.Name), nil } -func New() (*Warehouse, error) { +func New() (*Pkger, error) { info, err := here.Current() if err != nil { return nil, err } - return &Warehouse{ + return &Pkger{ infos: &maps.Infos{}, paths: &maps.Paths{ Current: info, @@ -53,7 +53,7 @@ func New() (*Warehouse, error) { }, nil } -func (fx *Warehouse) Create(name string) (pkging.File, error) { +func (fx *Pkger) Create(name string) (pkging.File, error) { name, err := fx.Abs(name) if err != nil { return nil, err @@ -65,11 +65,11 @@ func (fx *Warehouse) Create(name string) (pkging.File, error) { return NewFile(fx, f) } -func (f *Warehouse) Current() (here.Info, error) { +func (f *Pkger) Current() (here.Info, error) { return f.current, nil } -func (f *Warehouse) Info(p string) (here.Info, error) { +func (f *Pkger) Info(p string) (here.Info, error) { info, ok := f.infos.Load(p) if ok { return info, nil @@ -83,7 +83,7 @@ func (f *Warehouse) Info(p string) (here.Info, error) { return info, nil } -func (f *Warehouse) MkdirAll(p string, perm os.FileMode) error { +func (f *Pkger) MkdirAll(p string, perm os.FileMode) error { p, err := f.Abs(p) if err != nil { return err @@ -91,7 +91,7 @@ func (f *Warehouse) MkdirAll(p string, perm os.FileMode) error { return os.MkdirAll(p, perm) } -func (fx *Warehouse) Open(name string) (pkging.File, error) { +func (fx *Pkger) Open(name string) (pkging.File, error) { name, err := fx.Abs(name) if err != nil { return nil, err @@ -103,11 +103,11 @@ func (fx *Warehouse) Open(name string) (pkging.File, error) { return NewFile(fx, f) } -func (f *Warehouse) Parse(p string) (pkging.Path, error) { +func (f *Pkger) Parse(p string) (pkging.Path, error) { return f.paths.Parse(p) } -func (f *Warehouse) ReadFile(s string) ([]byte, error) { +func (f *Pkger) ReadFile(s string) ([]byte, error) { s, err := f.Abs(s) if err != nil { return nil, err @@ -115,7 +115,7 @@ func (f *Warehouse) ReadFile(s string) ([]byte, error) { return ioutil.ReadFile(s) } -func (f *Warehouse) Stat(name string) (os.FileInfo, error) { +func (f *Pkger) Stat(name string) (os.FileInfo, error) { pt, err := f.Parse(name) if err != nil { return nil, err @@ -136,7 +136,7 @@ func (f *Warehouse) Stat(name string) (os.FileInfo, error) { return info, nil } -func (f *Warehouse) Walk(p string, wf filepath.WalkFunc) error { +func (f *Pkger) Walk(p string, wf filepath.WalkFunc) error { fp, err := f.Abs(p) if err != nil { return err @@ -162,7 +162,7 @@ func (f *Warehouse) Walk(p string, wf filepath.WalkFunc) error { return err } -func (fx *Warehouse) Remove(name string) error { +func (fx *Pkger) Remove(name string) error { name, err := fx.Abs(name) if err != nil { return err @@ -170,7 +170,7 @@ func (fx *Warehouse) Remove(name string) error { return os.Remove(name) } -func (fx *Warehouse) RemoveAll(name string) error { +func (fx *Pkger) RemoveAll(name string) error { name, err := fx.Abs(name) if err != nil { return err diff --git a/pkging/osware/warehouse_test.go b/pkging/stdos/stdos_test.go similarity index 51% rename from pkging/osware/warehouse_test.go rename to pkging/stdos/stdos_test.go index 44324db..e61edc0 100644 --- a/pkging/osware/warehouse_test.go +++ b/pkging/stdos/stdos_test.go @@ -1,23 +1,23 @@ -package hdware +package stdos import ( "path/filepath" "testing" - "github.com/markbates/pkger/pkging/waretest" + "github.com/markbates/pkger/pkging/pkgtest" "github.com/stretchr/testify/require" ) -func Test_Warehouse(t *testing.T) { +func Test_Pkger(t *testing.T) { r := require.New(t) mypkging, err := New() r.NoError(err) - mypkging.current.Dir = filepath.Join(mypkging.current.Dir, ".waretest") + mypkging.current.Dir = filepath.Join(mypkging.current.Dir, ".pkgtest") mypkging.paths.Current = mypkging.current - suite, err := waretest.NewSuite(mypkging) + suite, err := pkgtest.NewSuite(mypkging) r.NoError(err) suite.Test(t) diff --git a/pkging/waretest/waretest.go b/pkging/waretest/waretest.go deleted file mode 100644 index 92b37c8..0000000 --- a/pkging/waretest/waretest.go +++ /dev/null @@ -1 +0,0 @@ -package waretest From 49d408c229da47afea34afbcd78e619be8e6ace8 Mon Sep 17 00:00:00 2001 From: Mark Bates Date: Tue, 3 Sep 2019 11:47:19 -0400 Subject: [PATCH 30/46] harold's super service --- pkging/pkgtest/suite.go | 21 +++++++------- pkging/pkgutil/file.go | 61 ++++++++++++++++++++++++++++++++++++++++- pkging/stdos/stdos.go | 12 ++++++++ 3 files changed, 82 insertions(+), 12 deletions(-) diff --git a/pkging/pkgtest/suite.go b/pkging/pkgtest/suite.go index af4fe78..7fbdc40 100644 --- a/pkging/pkgtest/suite.go +++ b/pkging/pkgtest/suite.go @@ -250,22 +250,21 @@ func (s Suite) Test_Open_File(t *testing.T) { body := "!" + pt.String() - f1, err := s.Create(tt.in) + pkgutil.WriteFile(s, tt.in, []byte(body), 0644) + + f, err := s.Open(tt.in) r.NoError(err) - _, err = io.Copy(f1, strings.NewReader(body)) - r.NoError(err) - r.NoError(f1.Close()) - - f2, err := s.Open(tt.in) - r.NoError(err) - - r.Equal(pt.Name, f2.Path().Name) - b, err := ioutil.ReadAll(f2) + r.Equal(pt.Name, f.Path().Name) + b, err := ioutil.ReadAll(f) r.NoError(err) r.Equal(body, string(b)) - r.NoError(f2.Close()) + b, err = pkgutil.ReadFile(s, tt.in) + r.NoError(err) + r.Equal(body, string(b)) + + r.NoError(f.Close()) }) } } diff --git a/pkging/pkgutil/file.go b/pkging/pkgutil/file.go index b7505a7..fb4760c 100644 --- a/pkging/pkgutil/file.go +++ b/pkging/pkgutil/file.go @@ -1,13 +1,43 @@ package pkgutil import ( + "io" "io/ioutil" + "os" + "sort" "github.com/markbates/pkger/pkging" ) +type Opener interface { + Open(name string) (pkging.File, error) +} + +type Creator interface { + Create(name string) (pkging.File, error) +} + +type OpenFiler interface { + OpenFile(name string, flag int, perm os.FileMode) (pkging.File, error) +} + +// ReadDir reads the directory named by dirname and returns a list of directory entries sorted by filename. +func ReadDir(pkg Opener, dirname string) ([]os.FileInfo, error) { + f, err := pkg.Open(dirname) + if err != nil { + return nil, err + } + list, err := f.Readdir(-1) + f.Close() + if err != nil { + return nil, err + } + sort.Slice(list, func(i, j int) bool { return list[i].Name() < list[j].Name() }) + return list, nil +} + // ReadFile reads the file named by filename and returns the contents. A successful call returns err == nil, not err == EOF. Because ReadFile reads the whole file, it does not treat an EOF from Read as an error to be reported. -func ReadFile(pkg pkging.Pkger, s string) ([]byte, error) { +func ReadFile(pkg Opener, s string) ([]byte, error) { f, err := pkg.Open(s) if err != nil { return nil, err @@ -15,3 +45,32 @@ func ReadFile(pkg pkging.Pkger, s string) ([]byte, error) { defer f.Close() return ioutil.ReadAll(f) } + +// WriteFile writes data to a file named by filename. If the file does not exist, WriteFile creates it with permissions perm; otherwise WriteFile truncates it before writing. +func WriteFile(pkg Creator, filename string, data []byte, perm os.FileMode) error { + var f pkging.File + var err error + + if of, ok := pkg.(OpenFiler); ok { + f, err = of.OpenFile(filename, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm) + if err != nil { + return err + } + } + + if f == nil { + f, err = pkg.Create(filename) + if err != nil { + return err + } + } + + n, err := f.Write(data) + if err == nil && n < len(data) { + err = io.ErrShortWrite + } + if err1 := f.Close(); err == nil { + err = err1 + } + return err +} diff --git a/pkging/stdos/stdos.go b/pkging/stdos/stdos.go index 44ffa0e..d88d148 100644 --- a/pkging/stdos/stdos.go +++ b/pkging/stdos/stdos.go @@ -20,6 +20,18 @@ type Pkger struct { current here.Info } +func (p *Pkger) OpenFile(name string, flag int, perm os.FileMode) (pkging.File, error) { + name, err := p.Abs(name) + if err != nil { + return nil, err + } + f, err := os.OpenFile(name, flag, perm) + if err != nil { + return nil, err + } + return NewFile(p, f) +} + func (f *Pkger) Abs(p string) (string, error) { pt, err := f.Parse(p) if err != nil { From aff26c9df70940b1e39b54a0fb650e197a29ea64 Mon Sep 17 00:00:00 2001 From: Mark Bates Date: Tue, 3 Sep 2019 12:02:55 -0400 Subject: [PATCH 31/46] something is beautiful and true --- pkging/pkgtest/file.go | 71 +++++++++++++++++++++++++++++++++++++++++ pkging/pkgtest/suite.go | 42 ------------------------ pkging/pkgtest/util.go | 52 ++++++++++++++++++++++++++++++ 3 files changed, 123 insertions(+), 42 deletions(-) create mode 100644 pkging/pkgtest/file.go create mode 100644 pkging/pkgtest/util.go diff --git a/pkging/pkgtest/file.go b/pkging/pkgtest/file.go new file mode 100644 index 0000000..ca537a6 --- /dev/null +++ b/pkging/pkgtest/file.go @@ -0,0 +1,71 @@ +package pkgtest + +import ( + "path/filepath" + "testing" + + "github.com/markbates/pkger/pkging/pkgutil" + "github.com/stretchr/testify/require" +) + +func (s Suite) Test_File_Info(t *testing.T) { + r := require.New(t) + cur, err := s.Current() + r.NoError(err) + + ip := cur.ImportPath + table := []struct { + in string + }{ + {in: mould}, + {in: ":" + mould}, + {in: ip + ":" + mould}, + } + + for _, tt := range table { + t.Run(tt.in, func(st *testing.T) { + r := require.New(st) + + r.NoError(s.RemoveAll(mould)) + r.NoError(s.MkdirAll(filepath.Dir(tt.in), 0755)) + err := pkgutil.WriteFile(s, tt.in, []byte(mould), 0644) + r.NoError(err) + + f, err := s.Open(tt.in) + r.NoError(err) + r.Equal(cur.ImportPath, f.Info().ImportPath) + }) + } +} + +func (s Suite) Test_File_Name(t *testing.T) { + panic("not implemented") +} + +func (s Suite) Test_File_Open(t *testing.T) { + panic("not implemented") +} + +func (s Suite) Test_File_Path(t *testing.T) { + panic("not implemented") +} + +func (s Suite) Test_File_Read(t *testing.T) { + panic("not implemented") +} + +func (s Suite) Test_File_Readdir(t *testing.T) { + panic("not implemented") +} + +func (s Suite) Test_File_Seek(t *testing.T) { + panic("not implemented") +} + +func (s Suite) Test_File_Stat(t *testing.T) { + panic("not implemented") +} + +func (s Suite) Test_File_Write(t *testing.T) { + panic("not implemented") +} diff --git a/pkging/pkgtest/suite.go b/pkging/pkgtest/suite.go index 7fbdc40..13b9e34 100644 --- a/pkging/pkgtest/suite.go +++ b/pkging/pkgtest/suite.go @@ -428,45 +428,3 @@ func (s Suite) Test_HTTP_Open(t *testing.T) { func (s Suite) Test_HTTP_Readdir(t *testing.T) { panic("not implemented") } - -func (s Suite) Test_ReadFile(t *testing.T) { - r := require.New(t) - - cur, err := s.Current() - r.NoError(err) - - ip := cur.ImportPath - table := []struct { - in string - }{ - {in: mould}, - {in: ":" + mould}, - {in: ip + ":" + mould}, - {in: hart}, - } - - for _, tt := range table { - t.Run(tt.in, func(st *testing.T) { - - r := require.New(st) - - pt, err := s.Parse(tt.in) - r.NoError(err) - - r.NoError(s.RemoveAll(pt.String())) - r.NoError(s.MkdirAll(filepath.Dir(pt.Name), 0755)) - - f, err := s.Create(tt.in) - r.NoError(err) - - body := "!" + pt.String() - _, err = io.Copy(f, strings.NewReader(body)) - r.NoError(err) - r.NoError(f.Close()) - - b, err := pkgutil.ReadFile(s, tt.in) - r.NoError(err) - r.Equal(body, string(b)) - }) - } -} diff --git a/pkging/pkgtest/util.go b/pkging/pkgtest/util.go new file mode 100644 index 0000000..7c7689f --- /dev/null +++ b/pkging/pkgtest/util.go @@ -0,0 +1,52 @@ +package pkgtest + +import ( + "io" + "path/filepath" + "strings" + "testing" + + "github.com/markbates/pkger/pkging/pkgutil" + "github.com/stretchr/testify/require" +) + +func (s Suite) Test_Util_ReadFile(t *testing.T) { + r := require.New(t) + cur, err := s.Current() + r.NoError(err) + + ip := cur.ImportPath + table := []struct { + in string + }{ + {in: mould}, + {in: ":" + mould}, + {in: ip + ":" + mould}, + {in: hart}, + } + + for _, tt := range table { + t.Run(tt.in, func(st *testing.T) { + + r := require.New(st) + + pt, err := s.Parse(tt.in) + r.NoError(err) + + r.NoError(s.RemoveAll(pt.String())) + r.NoError(s.MkdirAll(filepath.Dir(pt.Name), 0755)) + + f, err := s.Create(tt.in) + r.NoError(err) + + body := "!" + pt.String() + _, err = io.Copy(f, strings.NewReader(body)) + r.NoError(err) + r.NoError(f.Close()) + + b, err := pkgutil.ReadFile(s, tt.in) + r.NoError(err) + r.Equal(body, string(b)) + }) + } +} From c129ccbfe07a43d7790c50aae1519967d280e97b Mon Sep 17 00:00:00 2001 From: Mark Bates Date: Tue, 3 Sep 2019 12:41:21 -0400 Subject: [PATCH 32/46] don't mind --- pkging/mem/file.go | 8 ++- pkging/mem/mem.go | 22 ++----- pkging/mem/walk.go | 12 ++++ pkging/pkgtest/file.go | 14 +---- pkging/pkgtest/http.go | 140 +++++++++++++++++++++++++++++++++++++++++ pkging/stdos/file.go | 18 +++++- 6 files changed, 181 insertions(+), 33 deletions(-) create mode 100644 pkging/pkgtest/http.go diff --git a/pkging/mem/file.go b/pkging/mem/file.go index 6f32073..af9d829 100644 --- a/pkging/mem/file.go +++ b/pkging/mem/file.go @@ -8,6 +8,7 @@ import ( "net/http" "os" "path" + "path/filepath" "strings" "time" @@ -149,10 +150,13 @@ func (f *File) Readdir(count int) ([]os.FileInfo, error) { if pt.Name == f.parent.Name { return nil } - // if f.parent.Name != "/" { + info = pkging.WithName(strings.TrimPrefix(info.Name(), f.parent.Name), info) - // } infos = append(infos, info) + if info.IsDir() && path != root { + return filepath.SkipDir + } + return nil }) diff --git a/pkging/mem/mem.go b/pkging/mem/mem.go index d0bf18c..2eac9ff 100644 --- a/pkging/mem/mem.go +++ b/pkging/mem/mem.go @@ -86,26 +86,12 @@ func (fx *Pkger) RemoveAll(name string) error { return err } - return fx.Walk("/", func(path string, info os.FileInfo, err error) error { - if err != nil { - return err + fx.files.Range(func(key pkging.Path, file pkging.File) bool { + if strings.HasPrefix(key.Name, pt.Name) { + fx.files.Delete(key) } - - if !strings.HasPrefix(path, pt.String()) { - return nil - } - - ph, err := fx.Parse(path) - if err != nil { - return err - } - fx.files.Delete(ph) - return nil + return true }) - if _, ok := fx.files.Load(pt); !ok { - return &os.PathError{"remove", pt.String(), fmt.Errorf("no such file or directory")} - } - fx.files.Delete(pt) return nil } diff --git a/pkging/mem/walk.go b/pkging/mem/walk.go index 96f7421..f608328 100644 --- a/pkging/mem/walk.go +++ b/pkging/mem/walk.go @@ -15,10 +15,16 @@ func (f *Pkger) Walk(p string, wf filepath.WalkFunc) error { if err != nil { return err } + + skip := "!" + for _, k := range keys { if !strings.HasPrefix(k.Name, pt.Name) { continue } + if strings.HasPrefix(k.Name, skip) { + continue + } fl, ok := f.files.Load(k) if !ok { return fmt.Errorf("could not find %s", k) @@ -30,6 +36,12 @@ func (f *Pkger) Walk(p string, wf filepath.WalkFunc) error { fi = pkging.WithName(strings.TrimPrefix(k.Name, pt.Name), fi) err = wf(k.String(), fi, nil) + if err == filepath.SkipDir { + + skip = k.Name + continue + } + if err != nil { return err } diff --git a/pkging/pkgtest/file.go b/pkging/pkgtest/file.go index ca537a6..11e5a80 100644 --- a/pkging/pkgtest/file.go +++ b/pkging/pkgtest/file.go @@ -33,23 +33,13 @@ func (s Suite) Test_File_Info(t *testing.T) { f, err := s.Open(tt.in) r.NoError(err) + r.Equal(mould, f.Name()) r.Equal(cur.ImportPath, f.Info().ImportPath) + r.NoError(f.Close()) }) } } -func (s Suite) Test_File_Name(t *testing.T) { - panic("not implemented") -} - -func (s Suite) Test_File_Open(t *testing.T) { - panic("not implemented") -} - -func (s Suite) Test_File_Path(t *testing.T) { - panic("not implemented") -} - func (s Suite) Test_File_Read(t *testing.T) { panic("not implemented") } diff --git a/pkging/pkgtest/http.go b/pkging/pkgtest/http.go new file mode 100644 index 0000000..292dcb4 --- /dev/null +++ b/pkging/pkgtest/http.go @@ -0,0 +1,140 @@ +package pkgtest + +import ( + "io/ioutil" + "net/http" + "net/http/httptest" + "path/filepath" + "testing" + + "github.com/markbates/pkger/pkging/pkgutil" + "github.com/stretchr/testify/require" +) + +// examples/app +// ├── Dockerfile +// ├── Makefile +// ├── go.mod +// ├── go.sum +// ├── main.go +// ├── public +// │   ├── images +// │   │   ├── mark-small.png +// │   │   ├── mark.png +// │   │   ├── mark_250px.png +// │   │   └── mark_400px.png +// │   └── index.html +// └── templates +// ├── a.txt +// └── b +// └── b.txt + +func (s Suite) LoadFolder() error { + files := []string{ + "/main.go", + "/public/images/mark.png", + "/public/index.html", + "/templates/a.txt", + "/templates/b/b.txt", + } + + for _, f := range files { + if err := s.MkdirAll(filepath.Dir(f), 0755); err != nil { + return err + } + if err := pkgutil.WriteFile(s, f, []byte("!"+f), 0644); err != nil { + return err + } + } + return nil +} + +func (s Suite) Test_HTTP_Dir(t *testing.T) { + r := require.New(t) + + cur, err := s.Current() + r.NoError(err) + ip := cur.ImportPath + + r.NoError(s.LoadFolder()) + + table := []struct { + in string + req string + exp string + }{ + {in: "/", req: "/", exp: `>/public//public//public//mark.png`) +// r.NotContains(string(b), `/public`) +// r.NotContains(string(b), `/images`) +// r.NotContains(string(b), `/go.mod`) +// } diff --git a/pkging/stdos/file.go b/pkging/stdos/file.go index fd64c9d..56bc051 100644 --- a/pkging/stdos/file.go +++ b/pkging/stdos/file.go @@ -18,6 +18,22 @@ type File struct { pkging pkging.Pkger } +type HTTPFile struct { + http.File +} + +func (f *HTTPFile) Readdir(n int) ([]os.FileInfo, error) { + infos, err := f.File.Readdir(n) + if err != nil { + return nil, err + } + + for i, info := range infos { + infos[i] = pkging.NewFileInfo(info) + } + return infos, nil +} + func NewFile(fx pkging.Pkger, osf *os.File) (*File, error) { pt, err := fx.Parse(osf.Name()) @@ -62,7 +78,7 @@ func (f *File) Name() string { } func (f *File) Open(name string) (http.File, error) { - return f.File, nil + return &HTTPFile{f.File}, nil } func (f *File) Path() pkging.Path { From d453473dc0988e2488eca30eef4bc5edd8be928f Mon Sep 17 00:00:00 2001 From: Mark Bates Date: Tue, 3 Sep 2019 15:18:31 -0400 Subject: [PATCH 33/46] porch --- pkging/mem/create.go | 42 --------- pkging/mem/create_test.go | 80 ----------------- pkging/mem/file.go | 62 ++++++++++++++ pkging/mem/file_test.go | 58 ------------- pkging/mem/http.go | 1 - pkging/mem/http_test.go | 75 ---------------- pkging/mem/json.go | 66 --------------- pkging/mem/json_test.go | 33 -------- pkging/mem/mem.go | 165 ++++++++++++++++++++++++++++++++++++ pkging/mem/mkdirall.go | 61 ------------- pkging/mem/mkdirall_test.go | 25 ------ pkging/mem/open.go | 32 ------- pkging/mem/open_test.go | 24 ------ pkging/mem/stat.go | 18 ---- pkging/mem/stat_test.go | 18 ---- pkging/mem/walk.go | 50 ----------- pkging/mem/walk_test.go | 58 ------------- pkging/pkgtest/file.go | 38 ++++----- pkging/pkgtest/http.go | 44 ++++++++++ pkging/stdos/file.go | 19 +---- 20 files changed, 291 insertions(+), 678 deletions(-) delete mode 100644 pkging/mem/create.go delete mode 100644 pkging/mem/create_test.go delete mode 100644 pkging/mem/file_test.go delete mode 100644 pkging/mem/http.go delete mode 100644 pkging/mem/http_test.go delete mode 100644 pkging/mem/json.go delete mode 100644 pkging/mem/json_test.go delete mode 100644 pkging/mem/mkdirall.go delete mode 100644 pkging/mem/mkdirall_test.go delete mode 100644 pkging/mem/open.go delete mode 100644 pkging/mem/open_test.go delete mode 100644 pkging/mem/stat.go delete mode 100644 pkging/mem/stat_test.go delete mode 100644 pkging/mem/walk.go delete mode 100644 pkging/mem/walk_test.go diff --git a/pkging/mem/create.go b/pkging/mem/create.go deleted file mode 100644 index d8ae1ca..0000000 --- a/pkging/mem/create.go +++ /dev/null @@ -1,42 +0,0 @@ -package mem - -import ( - "path/filepath" - "time" - - "github.com/markbates/pkger/pkging" -) - -// no such file or directory -func (fx *Pkger) Create(name string) (pkging.File, error) { - pt, err := fx.Parse(name) - if err != nil { - return nil, err - } - - her, err := fx.Info(pt.Pkg) - if err != nil { - return nil, err - } - - if _, err := fx.Stat(filepath.Dir(pt.Name)); err != nil { - return nil, err - } - - f := &File{ - path: pt, - her: her, - info: &pkging.FileInfo{ - Details: pkging.Details{ - Name: pt.Name, - Mode: 0644, - ModTime: pkging.ModTime(time.Now()), - }, - }, - pkging: fx, - } - - fx.files.Store(pt, f) - - return f, nil -} diff --git a/pkging/mem/create_test.go b/pkging/mem/create_test.go deleted file mode 100644 index ed92d10..0000000 --- a/pkging/mem/create_test.go +++ /dev/null @@ -1,80 +0,0 @@ -package mem - -// func Test_Create(t *testing.T) { -// r := require.New(t) -// -// fs, err := New(here.Info{}) -// f, err := fs.Create("/hello.txt") -// r.NoError(err) -// r.NotNil(f) -// -// fi, err := f.Stat() -// r.NoError(err) -// -// r.Equal("/hello.txt", fi.Name()) -// r.Equal(os.FileMode(0666), fi.Mode()) -// r.NotZero(fi.ModTime()) -// } -// -// func Test_Create_Write(t *testing.T) { -// r := require.New(t) -// -// fs, err := New(here.Info{}) -// f, err := fs.Create("/hello.txt") -// r.NoError(err) -// r.NotNil(f) -// -// fi, err := f.Stat() -// r.NoError(err) -// r.Zero(fi.Size()) -// -// r.Equal("/hello.txt", fi.Name()) -// -// mt := fi.ModTime() -// r.NotZero(mt) -// -// sz, err := io.Copy(f, strings.NewReader(radio)) -// r.NoError(err) -// r.Equal(int64(1381), sz) -// -// r.NoError(f.Close()) -// r.Equal(int64(1381), fi.Size()) -// r.NotZero(fi.ModTime()) -// r.NotEqual(mt, fi.ModTime()) -// } -// -// const radio = `I was tuning in the shine on the late night dial -// Doing anything my radio advised -// With every one of those late night stations -// Playing songs bringing tears to my eyes -// I was seriously thinking about hiding the receiver -// When the switch broke 'cause it's old -// They're saying things that I can hardly believe -// They really think we're getting out of control -// Radio is a sound salvation -// Radio is cleaning up the nation -// They say you better listen to the voice of reason -// But they don't give you any choice 'cause they think that it's treason -// So you had better do as you are told -// You better listen to the radio -// I wanna bite the hand that feeds me -// I wanna bite that hand so badly -// I want to make them wish they'd never seen me -// Some of my friends sit around every evening -// And they worry about the times ahead -// But everybody else is overwhelmed by indifference -// And the promise of an early bed -// You either shut up or get cut up; they don't wanna hear about it -// It's only inches on the reel-to-reel -// And the radio is in the hands of such a lot of fools -// Tryin' to anesthetize the way that you feel -// Radio is a sound salvation -// Radio is cleaning up the nation -// They say you better listen to the voice of reason -// But they don't give you any choice 'cause they think that it's treason -// So you had better do as you are told -// You better listen to the radio -// Wonderful radio -// Marvelous radio -// Wonderful radio -// Radio, radio` diff --git a/pkging/mem/file.go b/pkging/mem/file.go index af9d829..803daed 100644 --- a/pkging/mem/file.go +++ b/pkging/mem/file.go @@ -152,6 +152,10 @@ func (f *File) Readdir(count int) ([]os.FileInfo, error) { } info = pkging.WithName(strings.TrimPrefix(info.Name(), f.parent.Name), info) + if minf, ok := info.(*pkging.FileInfo); ok { + minf.Details.Name = strings.TrimPrefix(info.Name(), "/") + info = minf + } infos = append(infos, info) if info.IsDir() && path != root { return filepath.SkipDir @@ -205,3 +209,61 @@ func (f *File) Open(name string) (http.File, error) { } return di, nil } + +func (f File) MarshalJSON() ([]byte, error) { + m := map[string]interface{}{ + "info": f.info, + "her": f.her, + "path": f.path, + "data": f.data, + "parent": f.parent, + } + return json.Marshal(m) +} + +func (f *File) UnmarshalJSON(b []byte) error { + m := map[string]json.RawMessage{} + if err := json.Unmarshal(b, &m); err != nil { + return err + } + + info, ok := m["info"] + if !ok { + return fmt.Errorf("missing info") + } + + f.info = &pkging.FileInfo{} + if err := json.Unmarshal(info, f.info); err != nil { + return err + } + + her, ok := m["her"] + if !ok { + return fmt.Errorf("missing her") + } + if err := json.Unmarshal(her, &f.her); err != nil { + return err + } + + path, ok := m["path"] + if !ok { + return fmt.Errorf("missing path") + } + if err := json.Unmarshal(path, &f.path); err != nil { + return err + } + + parent, ok := m["parent"] + if !ok { + return fmt.Errorf("missing parent") + } + if err := json.Unmarshal(parent, &f.parent); err != nil { + return err + } + + if err := json.Unmarshal(m["data"], &f.data); err != nil { + return err + } + + return nil +} diff --git a/pkging/mem/file_test.go b/pkging/mem/file_test.go deleted file mode 100644 index 2903001..0000000 --- a/pkging/mem/file_test.go +++ /dev/null @@ -1,58 +0,0 @@ -package mem - -// func Test_File_Read_Memory(t *testing.T) { -// r := require.New(t) -// -// fs, err := New(here.Info{}) -// r.NoError(err) -// -// f, err := fs.Create("/file_test.go") -// r.NoError(err) -// _, err = io.Copy(f, bytes.NewReader([]byte("hi!"))) -// r.NoError(err) -// r.NoError(f.Close()) -// -// f, err = fs.Open("/file_test.go") -// r.NoError(err) -// fi, err := f.Stat() -// r.NoError(err) -// r.Equal("/file_test.go", fi.Name()) -// -// b, err := ioutil.ReadAll(f) -// r.NoError(err) -// r.Equal(string(b), "hi!") -// } -// -// func Test_File_Write(t *testing.T) { -// r := require.New(t) -// -// fs, err := New(here.Info{}) -// r.NoError(err) -// -// f, err := fs.Create("/hello.txt") -// r.NoError(err) -// r.NotNil(f) -// -// fi, err := f.Stat() -// r.NoError(err) -// r.Zero(fi.Size()) -// -// r.Equal("/hello.txt", fi.Name()) -// -// mt := fi.ModTime() -// r.NotZero(mt) -// -// sz, err := io.Copy(f, strings.NewReader(radio)) -// r.NoError(err) -// r.Equal(int64(1381), sz) -// -// // because windows can't handle the time precisely -// // enough, we have to *force* just a smidge of time -// // to ensure the two ModTime's are different. -// // i know, i hate it too. -// time.Sleep(time.Millisecond) -// r.NoError(f.Close()) -// r.Equal(int64(1381), fi.Size()) -// r.NotZero(fi.ModTime()) -// r.NotEqual(mt, fi.ModTime()) -// } diff --git a/pkging/mem/http.go b/pkging/mem/http.go deleted file mode 100644 index 6a9fb31..0000000 --- a/pkging/mem/http.go +++ /dev/null @@ -1 +0,0 @@ -package mem diff --git a/pkging/mem/http_test.go b/pkging/mem/http_test.go deleted file mode 100644 index 6719aa1..0000000 --- a/pkging/mem/http_test.go +++ /dev/null @@ -1,75 +0,0 @@ -package mem - -// func Test_HTTP_Dir(t *testing.T) { -// r := require.New(t) -// -// fs := NewPkger() -// -// r.NoError(Folder.Create(fs)) -// -// dir, err := fs.Open("/") -// r.NoError(err) -// ts := httptest.NewServer(http.FileServer(dir)) -// defer ts.Close() -// -// res, err := http.Get(ts.URL + "/") -// r.NoError(err) -// r.Equal(200, res.StatusCode) -// -// b, err := ioutil.ReadAll(res.Body) -// r.NoError(err) -// r.Contains(string(b), `/public/images/mark.png`) -// } -// -// func Test_HTTP_File_Memory(t *testing.T) { -// r := require.New(t) -// -// fs := NewPkger() -// r.NoError(Folder.Create(fs)) -// -// dir, err := fs.Open("/") -// r.NoError(err) -// ts := httptest.NewServer(http.FileServer(dir)) -// defer ts.Close() -// -// res, err := http.Get(ts.URL + "/public/images/mark.png") -// r.NoError(err) -// r.Equal(200, res.StatusCode) -// -// b, err := ioutil.ReadAll(res.Body) -// r.NoError(err) -// r.Contains(string(b), `!/public/images/mark.png`) -// } -// -// func Test_HTTP_Dir_Memory_StripPrefix(t *testing.T) { -// r := require.New(t) -// -// fs := NewPkger() -// r.NoError(Folder.Create(fs)) -// -// dir, err := fs.Open("/public") -// r.NoError(err) -// defer dir.Close() -// -// ts := httptest.NewServer(http.StripPrefix("/assets/", http.FileServer(dir))) -// defer ts.Close() -// -// res, err := http.Get(ts.URL + "/assets/images/mark.png") -// r.NoError(err) -// r.Equal(200, res.StatusCode) -// -// b, _ := ioutil.ReadAll(res.Body) -// // r.NoError(err) -// r.Contains(string(b), "!/public/images/mark.png") -// -// res, err = http.Get(ts.URL + "/assets/images/") -// r.NoError(err) -// r.Equal(200, res.StatusCode) -// -// b, _ = ioutil.ReadAll(res.Body) -// // r.NoError(err) -// r.Contains(string(b), `/mark.png`) -// r.NotContains(string(b), `/public`) -// r.NotContains(string(b), `/images`) -// r.NotContains(string(b), `/go.mod`) -// } diff --git a/pkging/mem/json.go b/pkging/mem/json.go deleted file mode 100644 index 55a626b..0000000 --- a/pkging/mem/json.go +++ /dev/null @@ -1,66 +0,0 @@ -package mem - -import ( - "encoding/json" - "fmt" - - "github.com/markbates/pkger/pkging" -) - -func (f File) MarshalJSON() ([]byte, error) { - m := map[string]interface{}{ - "info": f.info, - "her": f.her, - "path": f.path, - "data": f.data, - "parent": f.parent, - } - return json.Marshal(m) -} - -func (f *File) UnmarshalJSON(b []byte) error { - m := map[string]json.RawMessage{} - if err := json.Unmarshal(b, &m); err != nil { - return err - } - - info, ok := m["info"] - if !ok { - return fmt.Errorf("missing info") - } - - f.info = &pkging.FileInfo{} - if err := json.Unmarshal(info, f.info); err != nil { - return err - } - - her, ok := m["her"] - if !ok { - return fmt.Errorf("missing her") - } - if err := json.Unmarshal(her, &f.her); err != nil { - return err - } - - path, ok := m["path"] - if !ok { - return fmt.Errorf("missing path") - } - if err := json.Unmarshal(path, &f.path); err != nil { - return err - } - - parent, ok := m["parent"] - if !ok { - return fmt.Errorf("missing parent") - } - if err := json.Unmarshal(parent, &f.parent); err != nil { - return err - } - - if err := json.Unmarshal(m["data"], &f.data); err != nil { - return err - } - - return nil -} diff --git a/pkging/mem/json_test.go b/pkging/mem/json_test.go deleted file mode 100644 index f258cf4..0000000 --- a/pkging/mem/json_test.go +++ /dev/null @@ -1,33 +0,0 @@ -package mem - -// func Test_File_JSON(t *testing.T) { -// r := require.New(t) -// -// fs, err := New(here.Info{}) -// r.NoError(err) -// -// f, err := fs.Create("/radio.radio") -// r.NoError(err) -// _, err = io.Copy(f, strings.NewReader(radio)) -// r.NoError(err) -// r.NoError(f.Close()) -// -// f, err = fs.Open("/radio.radio") -// r.NoError(err) -// bi, err := f.Stat() -// r.NoError(err) -// -// mj, err := json.Marshal(f) -// r.NoError(err) -// -// f2 := &File{} -// -// r.NoError(json.Unmarshal(mj, f2)) -// -// ai, err := f2.Stat() -// r.NoError(err) -// -// r.Equal(bi.Size(), ai.Size()) -// -// r.Equal(radio, string(f2.data)) -// } diff --git a/pkging/mem/mem.go b/pkging/mem/mem.go index 2eac9ff..c1f3465 100644 --- a/pkging/mem/mem.go +++ b/pkging/mem/mem.go @@ -3,7 +3,9 @@ package mem import ( "fmt" "os" + "path/filepath" "strings" + "time" "github.com/markbates/pkger/here" "github.com/markbates/pkger/internal/maps" @@ -95,3 +97,166 @@ func (fx *Pkger) RemoveAll(name string) error { return nil } + +func (fx *Pkger) Create(name string) (pkging.File, error) { + pt, err := fx.Parse(name) + if err != nil { + return nil, err + } + + her, err := fx.Info(pt.Pkg) + if err != nil { + return nil, err + } + + if _, err := fx.Stat(filepath.Dir(pt.Name)); err != nil { + return nil, err + } + + f := &File{ + path: pt, + her: her, + info: &pkging.FileInfo{ + Details: pkging.Details{ + Name: pt.Name, + Mode: 0644, + ModTime: pkging.ModTime(time.Now()), + }, + }, + pkging: fx, + } + + fx.files.Store(pt, f) + + return f, nil +} + +func (fx *Pkger) MkdirAll(p string, perm os.FileMode) error { + path, err := fx.Parse(p) + if err != nil { + return err + } + root := path.Name + + cur, err := fx.Current() + if err != nil { + return err + } + for root != "" { + pt := pkging.Path{ + Pkg: path.Pkg, + Name: root, + } + if _, ok := fx.files.Load(pt); ok { + root = filepath.Dir(root) + if root == "/" || root == "\\" { + break + } + continue + } + f := &File{ + pkging: fx, + path: pt, + her: cur, + info: &pkging.FileInfo{ + Details: pkging.Details{ + Name: pt.Name, + Mode: perm, + ModTime: pkging.ModTime(time.Now()), + }, + }, + } + + if err != nil { + return err + } + f.info.Details.IsDir = true + f.info.Details.Mode = perm + if err := f.Close(); err != nil { + return err + } + fx.files.Store(pt, f) + root = filepath.Dir(root) + } + + return nil + +} + +func (fx *Pkger) Open(name string) (pkging.File, error) { + pt, err := fx.Parse(name) + if err != nil { + return nil, err + } + + fl, ok := fx.files.Load(pt) + if !ok { + return nil, fmt.Errorf("could not open %s", name) + } + f, ok := fl.(*File) + if !ok { + return nil, fmt.Errorf("could not open %s", name) + } + nf := &File{ + pkging: fx, + info: pkging.WithName(f.info.Name(), f.info), + path: f.path, + data: f.data, + her: f.her, + } + + return nf, nil +} + +func (fx *Pkger) Stat(name string) (os.FileInfo, error) { + pt, err := fx.Parse(name) + if err != nil { + return nil, err + } + f, ok := fx.files.Load(pt) + if ok { + return f.Stat() + } + return nil, fmt.Errorf("could not stat %s", pt) +} + +func (f *Pkger) Walk(p string, wf filepath.WalkFunc) error { + keys := f.files.Keys() + + pt, err := f.Parse(p) + if err != nil { + return err + } + + skip := "!" + + for _, k := range keys { + if !strings.HasPrefix(k.Name, pt.Name) { + continue + } + if strings.HasPrefix(k.Name, skip) { + continue + } + fl, ok := f.files.Load(k) + if !ok { + return fmt.Errorf("could not find %s", k) + } + fi, err := fl.Stat() + if err != nil { + return err + } + + fi = pkging.WithName(strings.TrimPrefix(k.Name, pt.Name), fi) + err = wf(k.String(), fi, nil) + if err == filepath.SkipDir { + + skip = k.Name + continue + } + + if err != nil { + return err + } + } + return nil +} diff --git a/pkging/mem/mkdirall.go b/pkging/mem/mkdirall.go deleted file mode 100644 index eb17709..0000000 --- a/pkging/mem/mkdirall.go +++ /dev/null @@ -1,61 +0,0 @@ -package mem - -import ( - "os" - "path/filepath" - "time" - - "github.com/markbates/pkger/pkging" -) - -func (fx *Pkger) MkdirAll(p string, perm os.FileMode) error { - path, err := fx.Parse(p) - if err != nil { - return err - } - root := path.Name - - cur, err := fx.Current() - if err != nil { - return err - } - for root != "" { - pt := pkging.Path{ - Pkg: path.Pkg, - Name: root, - } - if _, ok := fx.files.Load(pt); ok { - root = filepath.Dir(root) - if root == "/" || root == "\\" { - break - } - continue - } - f := &File{ - pkging: fx, - path: pt, - her: cur, - info: &pkging.FileInfo{ - Details: pkging.Details{ - Name: pt.Name, - Mode: perm, - ModTime: pkging.ModTime(time.Now()), - }, - }, - } - - if err != nil { - return err - } - f.info.Details.IsDir = true - f.info.Details.Mode = perm - if err := f.Close(); err != nil { - return err - } - fx.files.Store(pt, f) - root = filepath.Dir(root) - } - - return nil - -} diff --git a/pkging/mem/mkdirall_test.go b/pkging/mem/mkdirall_test.go deleted file mode 100644 index d8f4299..0000000 --- a/pkging/mem/mkdirall_test.go +++ /dev/null @@ -1,25 +0,0 @@ -package mem - -import ( - "os" - "testing" - - "github.com/markbates/pkger/here" - "github.com/stretchr/testify/require" -) - -func Test_MkdirAll(t *testing.T) { - r := require.New(t) - - fs, _ := New(here.Info{}) - - err := fs.MkdirAll("/foo/bar/baz", 0755) - r.NoError(err) - - fi, err := fs.Stat("/foo/bar/baz") - r.NoError(err) - - r.Equal("/foo/bar/baz", fi.Name()) - r.Equal(os.FileMode(0755), fi.Mode()) - r.True(fi.IsDir()) -} diff --git a/pkging/mem/open.go b/pkging/mem/open.go deleted file mode 100644 index cd56aac..0000000 --- a/pkging/mem/open.go +++ /dev/null @@ -1,32 +0,0 @@ -package mem - -import ( - "fmt" - - "github.com/markbates/pkger/pkging" -) - -func (fx *Pkger) Open(name string) (pkging.File, error) { - pt, err := fx.Parse(name) - if err != nil { - return nil, err - } - - fl, ok := fx.files.Load(pt) - if !ok { - return nil, fmt.Errorf("could not open %s", name) - } - f, ok := fl.(*File) - if !ok { - return nil, fmt.Errorf("could not open %s", name) - } - nf := &File{ - pkging: fx, - info: pkging.WithName(f.info.Name(), f.info), - path: f.path, - data: f.data, - her: f.her, - } - - return nf, nil -} diff --git a/pkging/mem/open_test.go b/pkging/mem/open_test.go deleted file mode 100644 index dfd8651..0000000 --- a/pkging/mem/open_test.go +++ /dev/null @@ -1,24 +0,0 @@ -package mem - -// func Test_Open(t *testing.T) { -// r := require.New(t) -// -// fs, err := New(here.Info{}) -// r.NoError(err) -// -// _, err = fs.Open("/i.dont.exist") -// r.Error(err) -// -// f, err := fs.Create("/i.exist") -// r.NoError(err) -// _, err = io.Copy(f, strings.NewReader(radio)) -// r.NoError(err) -// r.NoError(f.Close()) -// -// f, err = fs.Open("/i.exist") -// r.NoError(err) -// b, err := ioutil.ReadAll(f) -// r.NoError(err) -// r.NoError(f.Close()) -// r.Equal([]byte(radio), b) -// } diff --git a/pkging/mem/stat.go b/pkging/mem/stat.go deleted file mode 100644 index 1906418..0000000 --- a/pkging/mem/stat.go +++ /dev/null @@ -1,18 +0,0 @@ -package mem - -import ( - "fmt" - "os" -) - -func (fx *Pkger) Stat(name string) (os.FileInfo, error) { - pt, err := fx.Parse(name) - if err != nil { - return nil, err - } - f, ok := fx.files.Load(pt) - if ok { - return f.Stat() - } - return nil, fmt.Errorf("could not stat %s", pt) -} diff --git a/pkging/mem/stat_test.go b/pkging/mem/stat_test.go deleted file mode 100644 index 4a2817c..0000000 --- a/pkging/mem/stat_test.go +++ /dev/null @@ -1,18 +0,0 @@ -package mem - -// func Test_Stat(t *testing.T) { -// r := require.New(t) -// -// fs, err := New(here.Info{}) -// r.NoError(err) -// _, err = fs.Stat("/i.dont.exist") -// r.Error(err) -// -// f, err := fs.Create("/i.exist") -// r.NoError(err) -// r.NoError(f.Close()) -// -// fi, err := fs.Stat("/i.exist") -// r.NoError(err) -// r.Equal("/i.exist", fi.Name()) -// } diff --git a/pkging/mem/walk.go b/pkging/mem/walk.go deleted file mode 100644 index f608328..0000000 --- a/pkging/mem/walk.go +++ /dev/null @@ -1,50 +0,0 @@ -package mem - -import ( - "fmt" - "path/filepath" - "strings" - - "github.com/markbates/pkger/pkging" -) - -func (f *Pkger) Walk(p string, wf filepath.WalkFunc) error { - keys := f.files.Keys() - - pt, err := f.Parse(p) - if err != nil { - return err - } - - skip := "!" - - for _, k := range keys { - if !strings.HasPrefix(k.Name, pt.Name) { - continue - } - if strings.HasPrefix(k.Name, skip) { - continue - } - fl, ok := f.files.Load(k) - if !ok { - return fmt.Errorf("could not find %s", k) - } - fi, err := fl.Stat() - if err != nil { - return err - } - - fi = pkging.WithName(strings.TrimPrefix(k.Name, pt.Name), fi) - err = wf(k.String(), fi, nil) - if err == filepath.SkipDir { - - skip = k.Name - continue - } - - if err != nil { - return err - } - } - return nil -} diff --git a/pkging/mem/walk_test.go b/pkging/mem/walk_test.go deleted file mode 100644 index e36d03f..0000000 --- a/pkging/mem/walk_test.go +++ /dev/null @@ -1,58 +0,0 @@ -package mem - -// func Test_Walk(t *testing.T) { -// r := require.New(t) -// -// files := []struct { -// name string -// body string -// }{ -// {name: "/a/a.txt", body: "A"}, -// {name: "/a/a.md", body: "Amd"}, -// {name: "/b/c/d.txt", body: "B"}, -// {name: "/f.txt", body: "F"}, -// } -// -// sort.Slice(files, func(a, b int) bool { -// return files[a].name < files[b].name -// }) -// -// fs, err := New(here.Info{}) -// r.NoError(err) -// -// for _, file := range files { -// f, err := fs.Create(file.name) -// r.NoError(err) -// _, err = io.Copy(f, strings.NewReader(file.body)) -// r.NoError(err) -// r.NoError(f.Close()) -// } -// -// var found []string -// err = fs.Walk("/", func(path string, info os.FileInfo, err error) error { -// if err != nil { -// return err -// } -// -// found = append(found, path) -// return nil -// }) -// r.NoError(err) -// -// expected := []string{":/", ":/a", ":/a/a.md", ":/a/a.txt", ":/b", ":/b/c", ":/b/c/d.txt", ":/f.txt"} -// r.Equal(expected, found) -// -// found = []string{} -// err = fs.Walk("/a/", func(path string, info os.FileInfo, err error) error { -// if err != nil { -// return err -// } -// -// found = append(found, path) -// return nil -// }) -// r.NoError(err) -// -// expected = []string{":/a/a.md", ":/a/a.txt"} -// r.Equal(expected, found) -// } diff --git a/pkging/pkgtest/file.go b/pkging/pkgtest/file.go index 11e5a80..d42b1a8 100644 --- a/pkging/pkgtest/file.go +++ b/pkging/pkgtest/file.go @@ -40,22 +40,22 @@ func (s Suite) Test_File_Info(t *testing.T) { } } -func (s Suite) Test_File_Read(t *testing.T) { - panic("not implemented") -} - -func (s Suite) Test_File_Readdir(t *testing.T) { - panic("not implemented") -} - -func (s Suite) Test_File_Seek(t *testing.T) { - panic("not implemented") -} - -func (s Suite) Test_File_Stat(t *testing.T) { - panic("not implemented") -} - -func (s Suite) Test_File_Write(t *testing.T) { - panic("not implemented") -} +// func (s Suite) Test_File_Read(t *testing.T) { +// panic("not implemented") +// } +// +// func (s Suite) Test_File_Readdir(t *testing.T) { +// panic("not implemented") +// } +// +// func (s Suite) Test_File_Seek(t *testing.T) { +// panic("not implemented") +// } +// +// func (s Suite) Test_File_Stat(t *testing.T) { +// panic("not implemented") +// } +// +// func (s Suite) Test_File_Write(t *testing.T) { +// panic("not implemented") +// } diff --git a/pkging/pkgtest/http.go b/pkging/pkgtest/http.go index 292dcb4..9f80810 100644 --- a/pkging/pkgtest/http.go +++ b/pkging/pkgtest/http.go @@ -5,6 +5,7 @@ import ( "net/http" "net/http/httptest" "path/filepath" + "strings" "testing" "github.com/markbates/pkger/pkging/pkgutil" @@ -86,6 +87,49 @@ func (s Suite) Test_HTTP_Dir(t *testing.T) { } } +func (s Suite) Test_HTTP_Dir_IndexHTML(t *testing.T) { + r := require.New(t) + + cur, err := s.Current() + r.NoError(err) + ip := cur.ImportPath + + r.NoError(s.LoadFolder()) + + table := []struct { + in string + req string + }{ + {in: "/public", req: "/"}, + {in: ":" + "/public", req: "/"}, + {in: ip + ":" + "/public", req: "/"}, + } + + exp := "!/public/index.html" + for _, tt := range table { + t.Run(tt.in+exp, func(st *testing.T) { + r := require.New(st) + + dir, err := s.Open(tt.in) + r.NoError(err) + + ts := httptest.NewServer(http.FileServer(dir)) + defer ts.Close() + + res, err := http.Get(ts.URL + tt.req) + r.NoError(err) + r.Equal(200, res.StatusCode) + + b, err := ioutil.ReadAll(res.Body) + r.NoError(err) + + body := strings.TrimSpace(string(b)) + r.Equal(exp, body) + r.NotContains(body, "mark.png") + }) + } +} + // func (s Suite) Test_HTTP_File_Memory(t *testing.T) { // r := require.New(t) // diff --git a/pkging/stdos/file.go b/pkging/stdos/file.go index 56bc051..21dc58f 100644 --- a/pkging/stdos/file.go +++ b/pkging/stdos/file.go @@ -18,24 +18,7 @@ type File struct { pkging pkging.Pkger } -type HTTPFile struct { - http.File -} - -func (f *HTTPFile) Readdir(n int) ([]os.FileInfo, error) { - infos, err := f.File.Readdir(n) - if err != nil { - return nil, err - } - - for i, info := range infos { - infos[i] = pkging.NewFileInfo(info) - } - return infos, nil -} - func NewFile(fx pkging.Pkger, osf *os.File) (*File, error) { - pt, err := fx.Parse(osf.Name()) if err != nil { return nil, err @@ -78,7 +61,7 @@ func (f *File) Name() string { } func (f *File) Open(name string) (http.File, error) { - return &HTTPFile{f.File}, nil + return f.File, nil } func (f *File) Path() pkging.Path { From 2e1702c1e55be1ffe3b486fa9e34ce9fc45de822 Mon Sep 17 00:00:00 2001 From: Mark Bates Date: Tue, 3 Sep 2019 15:24:16 -0400 Subject: [PATCH 34/46] troubled times --- pkging/info.go | 22 ++++++++++++++++------ pkging/mem/file.go | 6 +----- pkging/pkgtest/http.go | 13 ++++++------- 3 files changed, 23 insertions(+), 18 deletions(-) diff --git a/pkging/info.go b/pkging/info.go index 3e6e97a..9d5f9b5 100644 --- a/pkging/info.go +++ b/pkging/info.go @@ -65,9 +65,22 @@ func NewFileInfo(info os.FileInfo) *FileInfo { } func WithName(name string, info os.FileInfo) *FileInfo { - if ft, ok := info.(*FileInfo); ok { - ft.Details.Name = cleanName(name) - return ft + s := cleanName(name) + + if !strings.HasPrefix(s, "/") { + s = "/" + s + } + + fo := NewFileInfo(info) + fo.Details.Name = cleanName(name) + return fo +} + +func WithRelName(name string, info os.FileInfo) *FileInfo { + s := cleanName(name) + + if !strings.HasPrefix(s, "/") { + s = "/" + s } fo := NewFileInfo(info) @@ -79,8 +92,5 @@ func cleanName(s string) string { if strings.Contains(s, "\\") { s = strings.Replace(s, "\\", "/", -1) } - if !strings.HasPrefix(s, "/") { - s = "/" + s - } return s } diff --git a/pkging/mem/file.go b/pkging/mem/file.go index 803daed..c0c1548 100644 --- a/pkging/mem/file.go +++ b/pkging/mem/file.go @@ -151,11 +151,7 @@ func (f *File) Readdir(count int) ([]os.FileInfo, error) { return nil } - info = pkging.WithName(strings.TrimPrefix(info.Name(), f.parent.Name), info) - if minf, ok := info.(*pkging.FileInfo); ok { - minf.Details.Name = strings.TrimPrefix(info.Name(), "/") - info = minf - } + info = pkging.WithRelName(strings.TrimPrefix(info.Name(), f.parent.Name), info) infos = append(infos, info) if info.IsDir() && path != root { return filepath.SkipDir diff --git a/pkging/pkgtest/http.go b/pkging/pkgtest/http.go index 9f80810..b6bf1b1 100644 --- a/pkging/pkgtest/http.go +++ b/pkging/pkgtest/http.go @@ -5,7 +5,6 @@ import ( "net/http" "net/http/httptest" "path/filepath" - "strings" "testing" "github.com/markbates/pkger/pkging/pkgutil" @@ -64,9 +63,9 @@ func (s Suite) Test_HTTP_Dir(t *testing.T) { req string exp string }{ - {in: "/", req: "/", exp: `>/public//public//public/public/public/public/ Date: Tue, 3 Sep 2019 16:38:48 -0400 Subject: [PATCH 35/46] dissident --- pkging/pkgtest/suite.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pkging/pkgtest/suite.go b/pkging/pkgtest/suite.go index 13b9e34..a9ed2fc 100644 --- a/pkging/pkgtest/suite.go +++ b/pkging/pkgtest/suite.go @@ -46,8 +46,7 @@ func (s Suite) Test(t *testing.T) { } func (s Suite) sub(t *testing.T, m reflect.Method) { - name := strings.TrimPrefix(m.Name, "Test_") - name = fmt.Sprintf("%T_%s", s.Pkger, name) + name := fmt.Sprintf("%T/%s", s.Pkger, m.Name) t.Run(name, func(st *testing.T) { defer func() { if err := recover(); err != nil { From 2261590e37a9527b9fcfee06669efe764929b8ed Mon Sep 17 00:00:00 2001 From: Mark Bates Date: Tue, 3 Sep 2019 16:42:47 -0400 Subject: [PATCH 36/46] little wing --- pkging/pkgtest/suite.go | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/pkging/pkgtest/suite.go b/pkging/pkgtest/suite.go index a9ed2fc..f182293 100644 --- a/pkging/pkgtest/suite.go +++ b/pkging/pkgtest/suite.go @@ -45,8 +45,7 @@ func (s Suite) Test(t *testing.T) { } } -func (s Suite) sub(t *testing.T, m reflect.Method) { - name := fmt.Sprintf("%T/%s", s.Pkger, m.Name) +func (s Suite) Run(t *testing.T, name string, fn func(t *testing.T)) { t.Run(name, func(st *testing.T) { defer func() { if err := recover(); err != nil { @@ -62,6 +61,13 @@ func (s Suite) sub(t *testing.T, m reflect.Method) { cleaner() defer cleaner() + fn(st) + }) +} + +func (s Suite) sub(t *testing.T, m reflect.Method) { + name := fmt.Sprintf("%T/%s", s.Pkger, m.Name) + s.Run(t, name, func(st *testing.T) { m.Func.Call([]reflect.Value{ reflect.ValueOf(s), reflect.ValueOf(st), @@ -104,7 +110,7 @@ func (s Suite) Test_Create(t *testing.T) { } for _, tt := range table { - t.Run(tt.in, func(st *testing.T) { + s.Run(t, tt.in, func(st *testing.T) { r := require.New(st) pt, err := s.Parse(tt.in) @@ -146,7 +152,7 @@ func (s Suite) Test_Create_No_MkdirAll(t *testing.T) { } for _, tt := range table { - t.Run(tt.in, func(st *testing.T) { + s.Run(t, tt.in, func(st *testing.T) { r := require.New(st) pt, err := s.Parse(tt.in) @@ -198,7 +204,7 @@ func (s Suite) Test_MkdirAll(t *testing.T) { } for _, tt := range table { - t.Run(tt.in, func(st *testing.T) { + s.Run(t, tt.in, func(st *testing.T) { r := require.New(st) pt, err := s.Parse(tt.in) @@ -237,7 +243,7 @@ func (s Suite) Test_Open_File(t *testing.T) { } for _, tt := range table { - t.Run(tt.in, func(st *testing.T) { + s.Run(t, tt.in, func(st *testing.T) { r := require.New(st) From ee082ed548f28a17245aca5d387003a030cded68 Mon Sep 17 00:00:00 2001 From: Mark Bates Date: Tue, 3 Sep 2019 16:45:32 -0400 Subject: [PATCH 37/46] dollar and a dream --- pkging/pkgtest/file.go | 2 +- pkging/pkgtest/http.go | 6 +++--- pkging/pkgtest/suite.go | 8 ++++---- pkging/pkgtest/util.go | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/pkging/pkgtest/file.go b/pkging/pkgtest/file.go index d42b1a8..11025f1 100644 --- a/pkging/pkgtest/file.go +++ b/pkging/pkgtest/file.go @@ -23,7 +23,7 @@ func (s Suite) Test_File_Info(t *testing.T) { } for _, tt := range table { - t.Run(tt.in, func(st *testing.T) { + s.Run(t, tt.in, func(st *testing.T) { r := require.New(st) r.NoError(s.RemoveAll(mould)) diff --git a/pkging/pkgtest/http.go b/pkging/pkgtest/http.go index b6bf1b1..bb761d9 100644 --- a/pkging/pkgtest/http.go +++ b/pkging/pkgtest/http.go @@ -93,8 +93,6 @@ func (s Suite) Test_HTTP_Dir_IndexHTML(t *testing.T) { r.NoError(err) ip := cur.ImportPath - r.NoError(s.LoadFolder()) - table := []struct { in string req string @@ -106,9 +104,11 @@ func (s Suite) Test_HTTP_Dir_IndexHTML(t *testing.T) { exp := "index.html" for _, tt := range table { - t.Run(tt.in+exp, func(st *testing.T) { + s.Run(t, tt.in+exp, func(st *testing.T) { r := require.New(st) + r.NoError(s.LoadFolder()) + dir, err := s.Open(tt.in) r.NoError(err) diff --git a/pkging/pkgtest/suite.go b/pkging/pkgtest/suite.go index f182293..b09186a 100644 --- a/pkging/pkgtest/suite.go +++ b/pkging/pkgtest/suite.go @@ -297,7 +297,7 @@ func (s Suite) Test_Parse(t *testing.T) { } for _, tt := range table { - t.Run(tt.in, func(st *testing.T) { + s.Run(t, tt.in, func(st *testing.T) { r := require.New(st) pt, err := s.Parse(tt.in) @@ -326,7 +326,7 @@ func (s Suite) Test_Stat_Error(t *testing.T) { } for _, tt := range table { - t.Run(tt.in, func(st *testing.T) { + s.Run(t, tt.in, func(st *testing.T) { r := require.New(st) @@ -360,7 +360,7 @@ func (s Suite) Test_Stat_Dir(t *testing.T) { } for _, tt := range table { - t.Run(tt.in, func(st *testing.T) { + s.Run(t, tt.in, func(st *testing.T) { r := require.New(st) @@ -394,7 +394,7 @@ func (s Suite) Test_Stat_File(t *testing.T) { } for _, tt := range table { - t.Run(tt.in, func(st *testing.T) { + s.Run(t, tt.in, func(st *testing.T) { r := require.New(st) diff --git a/pkging/pkgtest/util.go b/pkging/pkgtest/util.go index 7c7689f..5a71098 100644 --- a/pkging/pkgtest/util.go +++ b/pkging/pkgtest/util.go @@ -26,7 +26,7 @@ func (s Suite) Test_Util_ReadFile(t *testing.T) { } for _, tt := range table { - t.Run(tt.in, func(st *testing.T) { + s.Run(t, tt.in, func(st *testing.T) { r := require.New(st) From 5e7309c6abccd4113d1b3ab75ecb1f838b8ab5cc Mon Sep 17 00:00:00 2001 From: Mark Bates Date: Tue, 3 Sep 2019 16:46:51 -0400 Subject: [PATCH 38/46] hollywood cemetery --- pkging/pkgtest/http.go | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/pkging/pkgtest/http.go b/pkging/pkgtest/http.go index bb761d9..17b8d5b 100644 --- a/pkging/pkgtest/http.go +++ b/pkging/pkgtest/http.go @@ -56,8 +56,6 @@ func (s Suite) Test_HTTP_Dir(t *testing.T) { r.NoError(err) ip := cur.ImportPath - r.NoError(s.LoadFolder()) - table := []struct { in string req string @@ -69,20 +67,25 @@ func (s Suite) Test_HTTP_Dir(t *testing.T) { } for _, tt := range table { + s.Run(t, tt.in+tt.req, func(st *testing.T) { - dir, err := s.Open(tt.in) - r.NoError(err) - ts := httptest.NewServer(http.FileServer(dir)) - defer ts.Close() + r := require.New(t) + r.NoError(s.LoadFolder()) - res, err := http.Get(ts.URL + tt.req) - r.NoError(err) - r.Equal(200, res.StatusCode) + dir, err := s.Open(tt.in) + r.NoError(err) + ts := httptest.NewServer(http.FileServer(dir)) + defer ts.Close() - b, err := ioutil.ReadAll(res.Body) - r.NoError(err) - r.Contains(string(b), tt.exp) - r.NotContains(string(b), "mark.png") + res, err := http.Get(ts.URL + tt.req) + r.NoError(err) + r.Equal(200, res.StatusCode) + + b, err := ioutil.ReadAll(res.Body) + r.NoError(err) + r.Contains(string(b), tt.exp) + r.NotContains(string(b), "mark.png") + }) } } From 28af04274c9f5dbdbdb09f944053f065fcc2a5d4 Mon Sep 17 00:00:00 2001 From: Mark Bates Date: Tue, 3 Sep 2019 18:38:52 -0400 Subject: [PATCH 39/46] games of chance --- .gitignore | 1 + pkging/pkgtest/http.go | 53 +++++++++++++++++++++++++++++++----------- 2 files changed, 41 insertions(+), 13 deletions(-) diff --git a/.gitignore b/.gitignore index 6f31e5c..65a6e19 100644 --- a/.gitignore +++ b/.gitignore @@ -30,3 +30,4 @@ gin-bin .idea/ pkged.go cover.out +.pkgtest diff --git a/pkging/pkgtest/http.go b/pkging/pkgtest/http.go index 17b8d5b..b4d5c13 100644 --- a/pkging/pkgtest/http.go +++ b/pkging/pkgtest/http.go @@ -74,6 +74,8 @@ func (s Suite) Test_HTTP_Dir(t *testing.T) { dir, err := s.Open(tt.in) r.NoError(err) + defer dir.Close() + ts := httptest.NewServer(http.FileServer(dir)) defer ts.Close() @@ -114,6 +116,7 @@ func (s Suite) Test_HTTP_Dir_IndexHTML(t *testing.T) { dir, err := s.Open(tt.in) r.NoError(err) + defer dir.Close() ts := httptest.NewServer(http.FileServer(dir)) defer ts.Close() @@ -132,25 +135,49 @@ func (s Suite) Test_HTTP_Dir_IndexHTML(t *testing.T) { } } -// func (s Suite) Test_HTTP_File_Memory(t *testing.T) { +// func (s Suite) Test_HTTP_File(t *testing.T) { // r := require.New(t) // -// fs := NewPkger() -// r.NoError(Folder.Create(fs)) -// -// dir, err := fs.Open("/") +// cur, err := s.Current() // r.NoError(err) -// ts := httptest.NewServer(http.FileServer(dir)) -// defer ts.Close() +// ip := cur.ImportPath // -// res, err := http.Get(ts.URL + "/public/images/mark.png") -// r.NoError(err) -// r.Equal(200, res.StatusCode) +// table := []struct { +// in string +// }{ +// {in: "/public"}, +// {in: ":" + "/public"}, +// {in: ip + ":" + "/public"}, +// } +// +// for _, tt := range table { +// s.Run(t, tt.in, func(st *testing.T) { +// +// r := require.New(st) +// +// r.NoError(s.LoadFolder()) +// +// dir, err := s.Open(tt.in) +// r.NoError(err) +// defer dir.Close() +// +// ts := httptest.NewServer(http.FileServer(dir)) +// defer ts.Close() +// +// res, err := http.Get(ts.URL + "/images/mark.png") +// r.NoError(err) +// r.Equal(200, res.StatusCode) +// +// b, err := ioutil.ReadAll(res.Body) +// r.NoError(err) +// +// body := string(b) +// r.Contains(body, `!/public/images/mark.png`) +// }) +// } // -// b, err := ioutil.ReadAll(res.Body) -// r.NoError(err) -// r.Contains(string(b), `!/public/images/mark.png`) // } + // // func (s Suite) Test_HTTP_Dir_Memory_StripPrefix(t *testing.T) { // r := require.New(t) From b3ed58d6e97ca50002a19ba215fe6f5257ef4053 Mon Sep 17 00:00:00 2001 From: Mark Bates Date: Thu, 5 Sep 2019 12:22:35 -0400 Subject: [PATCH 40/46] ruby soho --- examples/app/go.mod | 4 +- examples/app/go.sum | 1 + examples/app/main.go | 6 +-- go.mod | 5 +-- go.sum | 9 ----- pkging/pkgtest/http.go | 84 +++++++++++++++++++++--------------------- pkging/stdos/file.go | 26 ++++++++++++- 7 files changed, 73 insertions(+), 62 deletions(-) diff --git a/examples/app/go.mod b/examples/app/go.mod index 0521468..184f927 100644 --- a/examples/app/go.mod +++ b/examples/app/go.mod @@ -2,4 +2,6 @@ module github.com/markbates/pkger/examples/app go 1.12 -require github.com/markbates/pkger v0.0.0-20190830024022-c5e3a7de4d41 +require github.com/markbates/pkger v0.0.0 + +replace github.com/markbates/pkger => ../../ diff --git a/examples/app/go.sum b/examples/app/go.sum index 9cf6194..d3cbc9f 100644 --- a/examples/app/go.sum +++ b/examples/app/go.sum @@ -10,6 +10,7 @@ github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/markbates/errx v1.1.0/go.mod h1:PLa46Oex9KNbVDZhKel8v1OT7hD5JZ2eI7AHhA0wswc= github.com/markbates/pkger v0.0.0-20190830024022-c5e3a7de4d41 h1:bFEHpLBby7Qdvq92qw0TudeOfUKIZLcrweE/MMlNueI= github.com/markbates/pkger v0.0.0-20190830024022-c5e3a7de4d41/go.mod h1:M9VeozwduQUCr6z54kJrK9JegpbOv4wiePSbgSbFOew= +github.com/markbates/pkger/examples/app v0.0.0-20190830175641-68f3a2a4571d/go.mod h1:cWIt8Tz1UjmFa2KRaVgTfWPfHP+gprnzxDxNpo4YDxo= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= diff --git a/examples/app/main.go b/examples/app/main.go index 28083e4..ef57b23 100644 --- a/examples/app/main.go +++ b/examples/app/main.go @@ -18,11 +18,7 @@ func main() { } defer pub.Close() - fi, err := pub.Stat() - if err != nil { - log.Fatal(err) - } - fmt.Println(fi) + fmt.Println(pub.Path()) mux.Handle("/t", http.StripPrefix("/t", tmplHandler())) mux.Handle("/", http.FileServer(pub)) diff --git a/go.mod b/go.mod index ef4f883..086da1b 100644 --- a/go.mod +++ b/go.mod @@ -1,11 +1,8 @@ module github.com/markbates/pkger -go 1.12 +go 1.13 require ( - github.com/davecgh/go-spew v1.1.1 // indirect - github.com/kr/pretty v0.1.0 // indirect github.com/markbates/errx v1.1.0 github.com/stretchr/testify v1.4.0 - gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect ) diff --git a/go.sum b/go.sum index c6cc8bc..fee900f 100644 --- a/go.sum +++ b/go.sum @@ -1,12 +1,5 @@ github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/markbates/errx v1.1.0 h1:QDFeR+UP95dO12JgW+tgi2UVfo0V8YBHiUIOaeBPiEI= github.com/markbates/errx v1.1.0/go.mod h1:PLa46Oex9KNbVDZhKel8v1OT7hD5JZ2eI7AHhA0wswc= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= @@ -16,7 +9,5 @@ github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJy github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/pkging/pkgtest/http.go b/pkging/pkgtest/http.go index b4d5c13..f0a88b4 100644 --- a/pkging/pkgtest/http.go +++ b/pkging/pkgtest/http.go @@ -135,48 +135,48 @@ func (s Suite) Test_HTTP_Dir_IndexHTML(t *testing.T) { } } -// func (s Suite) Test_HTTP_File(t *testing.T) { -// r := require.New(t) -// -// cur, err := s.Current() -// r.NoError(err) -// ip := cur.ImportPath -// -// table := []struct { -// in string -// }{ -// {in: "/public"}, -// {in: ":" + "/public"}, -// {in: ip + ":" + "/public"}, -// } -// -// for _, tt := range table { -// s.Run(t, tt.in, func(st *testing.T) { -// -// r := require.New(st) -// -// r.NoError(s.LoadFolder()) -// -// dir, err := s.Open(tt.in) -// r.NoError(err) -// defer dir.Close() -// -// ts := httptest.NewServer(http.FileServer(dir)) -// defer ts.Close() -// -// res, err := http.Get(ts.URL + "/images/mark.png") -// r.NoError(err) -// r.Equal(200, res.StatusCode) -// -// b, err := ioutil.ReadAll(res.Body) -// r.NoError(err) -// -// body := string(b) -// r.Contains(body, `!/public/images/mark.png`) -// }) -// } -// -// } +func (s Suite) Test_HTTP_File(t *testing.T) { + r := require.New(t) + + cur, err := s.Current() + r.NoError(err) + ip := cur.ImportPath + + table := []struct { + in string + }{ + {in: "/public"}, + {in: ":" + "/public"}, + {in: ip + ":" + "/public"}, + } + + for _, tt := range table { + s.Run(t, tt.in, func(st *testing.T) { + + r := require.New(st) + + r.NoError(s.LoadFolder()) + + dir, err := s.Open(tt.in) + r.NoError(err) + defer dir.Close() + + ts := httptest.NewServer(http.FileServer(dir)) + defer ts.Close() + + res, err := http.Get(ts.URL + "/images/mark.png") + r.NoError(err) + r.Equal(200, res.StatusCode) + + b, err := ioutil.ReadAll(res.Body) + r.NoError(err) + + body := string(b) + r.Contains(body, `!/public/images/mark.png`) + }) + } + +} // // func (s Suite) Test_HTTP_Dir_Memory_StripPrefix(t *testing.T) { diff --git a/pkging/stdos/file.go b/pkging/stdos/file.go index 21dc58f..303e697 100644 --- a/pkging/stdos/file.go +++ b/pkging/stdos/file.go @@ -3,6 +3,7 @@ package stdos import ( "net/http" "os" + "path" "github.com/markbates/pkger/here" "github.com/markbates/pkger/pkging" @@ -60,8 +61,31 @@ func (f *File) Name() string { return f.info.Name() } +type HTTP struct { + pkging.File + osf *os.File +} + +func (f *HTTP) Readdir(count int) ([]os.FileInfo, error) { + osinfos, err := f.osf.Readdir(count) + if err != nil { + return nil, err + } + + infos := make([]os.FileInfo, len(osinfos)) + for i, info := range osinfos { + infos[i] = pkging.WithName(info.Name(), info) + } + return infos, err +} + func (f *File) Open(name string) (http.File, error) { - return f.File, nil + fp := path.Join(f.Path().Name, name) + f2, err := f.pkging.Open(fp) + if err != nil { + return nil, err + } + return &HTTP{File: f2, osf: f.File}, nil } func (f *File) Path() pkging.Path { From 29b463b4204474953ae0d63411ea41dcd71609c6 Mon Sep 17 00:00:00 2001 From: Mark Bates Date: Thu, 5 Sep 2019 12:25:51 -0400 Subject: [PATCH 41/46] small town --- examples/app/main.go | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/examples/app/main.go b/examples/app/main.go index ef57b23..a892560 100644 --- a/examples/app/main.go +++ b/examples/app/main.go @@ -23,7 +23,14 @@ func main() { mux.Handle("/t", http.StripPrefix("/t", tmplHandler())) mux.Handle("/", http.FileServer(pub)) - log.Fatal(http.ListenAndServe(":3000", mux)) + log.Fatal(http.ListenAndServe(":3000", logger(mux))) +} + +func logger(h http.Handler) http.HandlerFunc { + return func(res http.ResponseWriter, req *http.Request) { + log.Println(req.Method, req.URL.String()) + h.ServeHTTP(res, req) + } } func tmplHandler() http.HandlerFunc { From e45df3e5ac67b0d2c303913c37e9ed7ae230f75d Mon Sep 17 00:00:00 2001 From: Mark Bates Date: Thu, 5 Sep 2019 12:30:13 -0400 Subject: [PATCH 42/46] nothing is how he feels --- pkging/pkgtest/suite.go | 22 +++++++--------------- pkging/stdos/stdos.go | 12 ------------ 2 files changed, 7 insertions(+), 27 deletions(-) diff --git a/pkging/pkgtest/suite.go b/pkging/pkgtest/suite.go index b09186a..7ddc8f5 100644 --- a/pkging/pkgtest/suite.go +++ b/pkging/pkgtest/suite.go @@ -418,18 +418,10 @@ func (s Suite) Test_Stat_File(t *testing.T) { } } -func (s Suite) Test_Walk(t *testing.T) { - panic("not implemented") -} - -func (s Suite) Test_Remove(t *testing.T) { - panic("not implemented") -} - -func (s Suite) Test_HTTP_Open(t *testing.T) { - panic("not implemented") -} - -func (s Suite) Test_HTTP_Readdir(t *testing.T) { - panic("not implemented") -} +// func (s Suite) Test_Walk(t *testing.T) { +// panic("not implemented") +// } +// +// func (s Suite) Test_Remove(t *testing.T) { +// panic("not implemented") +// } diff --git a/pkging/stdos/stdos.go b/pkging/stdos/stdos.go index d88d148..44ffa0e 100644 --- a/pkging/stdos/stdos.go +++ b/pkging/stdos/stdos.go @@ -20,18 +20,6 @@ type Pkger struct { current here.Info } -func (p *Pkger) OpenFile(name string, flag int, perm os.FileMode) (pkging.File, error) { - name, err := p.Abs(name) - if err != nil { - return nil, err - } - f, err := os.OpenFile(name, flag, perm) - if err != nil { - return nil, err - } - return NewFile(p, f) -} - func (f *Pkger) Abs(p string) (string, error) { pt, err := f.Parse(p) if err != nil { From bb509c2487b46af3e9e328cd28343d4ed07fa810 Mon Sep 17 00:00:00 2001 From: Mark Bates Date: Wed, 11 Sep 2019 21:29:39 -0400 Subject: [PATCH 43/46] hard candy --- Makefile | 2 +- examples/app/go.mod | 2 +- examples/app/go.sum | 12 -- here/dir.go | 46 ++++---- here/here.go | 18 +++ here/info_map.go | 87 +++++++++++++++ here/pkg.go | 24 ++-- internal/maps/files.go | 23 ---- internal/maps/infos.go | 23 ---- internal/maps/paths.go | 23 ---- pkging/mem/mem.go | 6 + pkging/mem/mem_test.go | 28 +++-- pkging/pkgtest/file.go | 14 ++- pkging/pkgtest/http.go | 45 +++++--- pkging/pkgtest/suite.go | 220 +++++++++++++++++++++++-------------- pkging/pkgtest/util.go | 20 ++-- pkging/stdos/stdos.go | 9 -- pkging/stdos/stdos_test.go | 27 +++-- 18 files changed, 375 insertions(+), 254 deletions(-) create mode 100644 here/info_map.go diff --git a/Makefile b/Makefile index 94018ac..b728e38 100644 --- a/Makefile +++ b/Makefile @@ -13,7 +13,7 @@ build: tidy make tidy test: tidy - $(GO_BIN) test -cover -tags ${TAGS} -timeout 5s ./... + $(GO_BIN) test -cover -tags ${TAGS} -timeout 5s -race ./... make tidy cov: diff --git a/examples/app/go.mod b/examples/app/go.mod index 184f927..fc5a5dd 100644 --- a/examples/app/go.mod +++ b/examples/app/go.mod @@ -1,6 +1,6 @@ module github.com/markbates/pkger/examples/app -go 1.12 +go 1.13 require github.com/markbates/pkger v0.0.0 diff --git a/examples/app/go.sum b/examples/app/go.sum index d3cbc9f..1945221 100644 --- a/examples/app/go.sum +++ b/examples/app/go.sum @@ -1,16 +1,6 @@ github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/markbates/errx v1.1.0/go.mod h1:PLa46Oex9KNbVDZhKel8v1OT7hD5JZ2eI7AHhA0wswc= -github.com/markbates/pkger v0.0.0-20190830024022-c5e3a7de4d41 h1:bFEHpLBby7Qdvq92qw0TudeOfUKIZLcrweE/MMlNueI= -github.com/markbates/pkger v0.0.0-20190830024022-c5e3a7de4d41/go.mod h1:M9VeozwduQUCr6z54kJrK9JegpbOv4wiePSbgSbFOew= -github.com/markbates/pkger/examples/app v0.0.0-20190830175641-68f3a2a4571d/go.mod h1:cWIt8Tz1UjmFa2KRaVgTfWPfHP+gprnzxDxNpo4YDxo= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -18,7 +8,5 @@ github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJy github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/here/dir.go b/here/dir.go index 1b37dde..d0d1034 100644 --- a/here/dir.go +++ b/here/dir.go @@ -8,34 +8,36 @@ import ( // Dir attempts to gather info for the requested directory. func Dir(p string) (Info, error) { - var i Info + return Cache(p, func(p string) (Info, error) { + var i Info - fi, err := os.Stat(p) - if err != nil { - return i, err - } + fi, err := os.Stat(p) + if err != nil { + return i, err + } - if !fi.IsDir() { - p = filepath.Dir(p) - } + if !fi.IsDir() { + p = filepath.Dir(p) + } - pwd, err := os.Getwd() - if err != nil { - return i, err - } + pwd, err := os.Getwd() + if err != nil { + return i, err + } - defer os.Chdir(pwd) + defer os.Chdir(pwd) - os.Chdir(p) + os.Chdir(p) - b, err := run("go", "list", "-json") - if err != nil { - return i, err - } + b, err := run("go", "list", "-json") + if err != nil { + return i, err + } - if err := json.Unmarshal(b, &i); err != nil { - return i, err - } + if err := json.Unmarshal(b, &i); err != nil { + return i, err + } - return i, nil + return i, nil + }) } diff --git a/here/here.go b/here/here.go index dc4ee62..a5a282f 100644 --- a/here/here.go +++ b/here/here.go @@ -4,8 +4,13 @@ import ( "bytes" "os" "os/exec" + "sync" ) +var cache = &infoMap{ + data: &sync.Map{}, +} + func run(n string, args ...string) ([]byte, error) { c := exec.Command(n, args...) @@ -19,3 +24,16 @@ func run(n string, args ...string) ([]byte, error) { return bb.Bytes(), nil } + +func Cache(p string, fn func(string) (Info, error)) (Info, error) { + i, ok := cache.Load(p) + if ok { + return i, nil + } + i, err := fn(p) + if err != nil { + return i, err + } + cache.Store(p, i) + return i, nil +} diff --git a/here/info_map.go b/here/info_map.go new file mode 100644 index 0000000..b9471ef --- /dev/null +++ b/here/info_map.go @@ -0,0 +1,87 @@ +// Code generated by github.com/gobuffalo/mapgen. DO NOT EDIT. + +package here + +import ( + "sort" + "sync" +) + +// infoMap wraps sync.Map and uses the following types: +// key: string +// value: Info +type infoMap struct { + data *sync.Map +} + +// Delete the key from the map +func (m *infoMap) Delete(key string) { + m.data.Delete(key) +} + +// Load the key from the map. +// Returns Info or bool. +// A false return indicates either the key was not found +// or the value is not of type Info +func (m *infoMap) Load(key string) (Info, bool) { + i, ok := m.data.Load(key) + if !ok { + return Info{}, false + } + s, ok := i.(Info) + return s, ok +} + +// LoadOrStore will return an existing key or +// store the value if not already in the map +func (m *infoMap) LoadOrStore(key string, value Info) (Info, bool) { + i, _ := m.data.LoadOrStore(key, value) + s, ok := i.(Info) + return s, ok +} + +// LoadOr will return an existing key or +// run the function and store the results +func (m *infoMap) LoadOr(key string, fn func(*infoMap) (Info, bool)) (Info, bool) { + i, ok := m.Load(key) + if ok { + return i, ok + } + i, ok = fn(m) + if ok { + m.Store(key, i) + return i, ok + } + return i, false +} + +// Range over the Info values in the map +func (m *infoMap) Range(f func(key string, value Info) bool) { + m.data.Range(func(k, v interface{}) bool { + key, ok := k.(string) + if !ok { + return false + } + value, ok := v.(Info) + if !ok { + return false + } + return f(key, value) + }) +} + +// Store a Info in the map +func (m *infoMap) Store(key string, value Info) { + m.data.Store(key, value) +} + +// Keys returns a list of keys in the map +func (m *infoMap) Keys() []string { + var keys []string + m.Range(func(key string, value Info) bool { + keys = append(keys, key) + return true + }) + sort.Strings(keys) + return keys +} diff --git a/here/pkg.go b/here/pkg.go index aeb2db2..3a2bc3c 100644 --- a/here/pkg.go +++ b/here/pkg.go @@ -1,6 +1,8 @@ package here -import "encoding/json" +import ( + "encoding/json" +) // Package attempts to gather info for the requested package. // @@ -12,14 +14,16 @@ import "encoding/json" // returned `Info` value and pass it to the `Dir(string) (Info, error)` // function to return the complete data. func Package(p string) (Info, error) { - var i Info - b, err := run("go", "list", "-json", "-find", p) - if err != nil { - return i, err - } - if err := json.Unmarshal(b, &i); err != nil { - return i, err - } + return Cache(p, func(p string) (Info, error) { + var i Info + b, err := run("go", "list", "-json", "-find", p) + if err != nil { + return i, err + } + if err := json.Unmarshal(b, &i); err != nil { + return i, err + } - return i, nil + return i, nil + }) } diff --git a/internal/maps/files.go b/internal/maps/files.go index ddd3ccd..bf5ab3a 100644 --- a/internal/maps/files.go +++ b/internal/maps/files.go @@ -85,29 +85,6 @@ func (m *Files) Load(key pkging.Path) (pkging.File, bool) { return s, ok } -// LoadOrStore will return an existing key or -// store the value if not already in the map -func (m *Files) LoadOrStore(key pkging.Path, value pkging.File) (pkging.File, bool) { - i, _ := m.Data().LoadOrStore(key, value) - s, ok := i.(pkging.File) - return s, ok -} - -// LoadOr will return an existing key or -// run the function and store the results -func (m *Files) LoadOr(key pkging.Path, fn func(*Files) (pkging.File, bool)) (pkging.File, bool) { - i, ok := m.Load(key) - if ok { - return i, ok - } - i, ok = fn(m) - if ok { - m.Store(key, i) - return i, ok - } - return i, false -} - // Range over the pkging.File values in the map func (m *Files) Range(f func(key pkging.Path, value pkging.File) bool) { m.Data().Range(func(k, v interface{}) bool { diff --git a/internal/maps/infos.go b/internal/maps/infos.go index a0d4871..0eed02f 100644 --- a/internal/maps/infos.go +++ b/internal/maps/infos.go @@ -71,29 +71,6 @@ func (m *Infos) Load(key string) (here.Info, bool) { return s, ok } -// LoadOrStore will return an existing key or -// store the value if not already in the map -func (m *Infos) LoadOrStore(key string, value here.Info) (here.Info, bool) { - i, _ := m.Data().LoadOrStore(key, value) - s, ok := i.(here.Info) - return s, ok -} - -// LoadOr will return an existing key or -// run the function and store the results -func (m *Infos) LoadOr(key string, fn func(*Infos) (here.Info, bool)) (here.Info, bool) { - i, ok := m.Load(key) - if ok { - return i, ok - } - i, ok = fn(m) - if ok { - m.Store(key, i) - return i, ok - } - return i, false -} - // Range over the here.Info values in the map func (m *Infos) Range(f func(key string, value here.Info) bool) { m.Data().Range(func(k, v interface{}) bool { diff --git a/internal/maps/paths.go b/internal/maps/paths.go index e114c5e..969df6b 100644 --- a/internal/maps/paths.go +++ b/internal/maps/paths.go @@ -74,29 +74,6 @@ func (m *Paths) Load(key string) (pkging.Path, bool) { return s, ok } -// LoadOrStore will return an existing key or -// store the value if not already in the map -func (m *Paths) LoadOrStore(key string, value pkging.Path) (pkging.Path, bool) { - i, _ := m.Data().LoadOrStore(key, value) - s, ok := i.(pkging.Path) - return s, ok -} - -// LoadOr will return an existing key or -// run the function and store the results -func (m *Paths) LoadOr(key string, fn func(*Paths) (pkging.Path, bool)) (pkging.Path, bool) { - i, ok := m.Load(key) - if ok { - return i, ok - } - i, ok = fn(m) - if ok { - m.Store(key, i) - return i, ok - } - return i, false -} - // Range over the Path values in the map func (m *Paths) Range(f func(key string, value pkging.Path) bool) { m.Data().Range(func(k, v interface{}) bool { diff --git a/pkging/mem/mem.go b/pkging/mem/mem.go index c1f3465..c1293f1 100644 --- a/pkging/mem/mem.go +++ b/pkging/mem/mem.go @@ -95,6 +95,12 @@ func (fx *Pkger) RemoveAll(name string) error { return true }) + fx.paths.Range(func(key string, value pkging.Path) bool { + if strings.HasPrefix(key, pt.Name) { + fx.paths.Delete(key) + } + return true + }) return nil } diff --git a/pkging/mem/mem_test.go b/pkging/mem/mem_test.go index 925b26b..79effb2 100644 --- a/pkging/mem/mem_test.go +++ b/pkging/mem/mem_test.go @@ -4,24 +4,28 @@ import ( "testing" "github.com/markbates/pkger/here" + "github.com/markbates/pkger/pkging" "github.com/markbates/pkger/pkging/pkgtest" - "github.com/stretchr/testify/require" ) func Test_Pkger(t *testing.T) { - r := require.New(t) + suite, err := pkgtest.NewSuite("memos", func() (pkging.Pkger, error) { + info, err := here.Current() + if err != nil { + return nil, err + } - info, err := here.Current() - r.NoError(err) - r.NotZero(info) + wh, err := New(info) + if err != nil { + return nil, err + } - wh, err := New(info) - r.NoError(err) - - WithInfo(wh, info) - - suite, err := pkgtest.NewSuite(wh) - r.NoError(err) + WithInfo(wh, info) + return wh, nil + }) + if err != nil { + t.Fatal(err) + } suite.Test(t) } diff --git a/pkging/pkgtest/file.go b/pkging/pkgtest/file.go index 11025f1..72d7fa6 100644 --- a/pkging/pkgtest/file.go +++ b/pkging/pkgtest/file.go @@ -10,7 +10,11 @@ import ( func (s Suite) Test_File_Info(t *testing.T) { r := require.New(t) - cur, err := s.Current() + + pkg, err := s.Make() + r.NoError(err) + + cur, err := pkg.Current() r.NoError(err) ip := cur.ImportPath @@ -26,12 +30,12 @@ func (s Suite) Test_File_Info(t *testing.T) { s.Run(t, tt.in, func(st *testing.T) { r := require.New(st) - r.NoError(s.RemoveAll(mould)) - r.NoError(s.MkdirAll(filepath.Dir(tt.in), 0755)) - err := pkgutil.WriteFile(s, tt.in, []byte(mould), 0644) + r.NoError(pkg.RemoveAll(mould)) + r.NoError(pkg.MkdirAll(filepath.Dir(tt.in), 0755)) + err := pkgutil.WriteFile(pkg, tt.in, []byte(mould), 0644) r.NoError(err) - f, err := s.Open(tt.in) + f, err := pkg.Open(tt.in) r.NoError(err) r.Equal(mould, f.Name()) r.Equal(cur.ImportPath, f.Info().ImportPath) diff --git a/pkging/pkgtest/http.go b/pkging/pkgtest/http.go index f0a88b4..2365bdf 100644 --- a/pkging/pkgtest/http.go +++ b/pkging/pkgtest/http.go @@ -7,6 +7,7 @@ import ( "path/filepath" "testing" + "github.com/markbates/pkger/pkging" "github.com/markbates/pkger/pkging/pkgutil" "github.com/stretchr/testify/require" ) @@ -29,7 +30,7 @@ import ( // └── b // └── b.txt -func (s Suite) LoadFolder() error { +func (s Suite) LoadFolder(pkg pkging.Pkger) error { files := []string{ "/main.go", "/public/images/mark.png", @@ -39,10 +40,10 @@ func (s Suite) LoadFolder() error { } for _, f := range files { - if err := s.MkdirAll(filepath.Dir(f), 0755); err != nil { + if err := pkg.MkdirAll(filepath.Dir(f), 0755); err != nil { return err } - if err := pkgutil.WriteFile(s, f, []byte("!"+f), 0644); err != nil { + if err := pkgutil.WriteFile(pkg, f, []byte("!"+f), 0644); err != nil { return err } } @@ -52,7 +53,10 @@ func (s Suite) LoadFolder() error { func (s Suite) Test_HTTP_Dir(t *testing.T) { r := require.New(t) - cur, err := s.Current() + pkg, err := s.Make() + r.NoError(err) + + cur, err := pkg.Current() r.NoError(err) ip := cur.ImportPath @@ -68,11 +72,13 @@ func (s Suite) Test_HTTP_Dir(t *testing.T) { for _, tt := range table { s.Run(t, tt.in+tt.req, func(st *testing.T) { + r := require.New(st) - r := require.New(t) - r.NoError(s.LoadFolder()) + pkg, err := s.Make() + r.NoError(err) + r.NoError(s.LoadFolder(pkg)) - dir, err := s.Open(tt.in) + dir, err := pkg.Open(tt.in) r.NoError(err) defer dir.Close() @@ -94,7 +100,10 @@ func (s Suite) Test_HTTP_Dir(t *testing.T) { func (s Suite) Test_HTTP_Dir_IndexHTML(t *testing.T) { r := require.New(t) - cur, err := s.Current() + pkg, err := s.Make() + r.NoError(err) + + cur, err := pkg.Current() r.NoError(err) ip := cur.ImportPath @@ -112,9 +121,12 @@ func (s Suite) Test_HTTP_Dir_IndexHTML(t *testing.T) { s.Run(t, tt.in+exp, func(st *testing.T) { r := require.New(st) - r.NoError(s.LoadFolder()) + pkg, err := s.Make() + r.NoError(err) - dir, err := s.Open(tt.in) + r.NoError(s.LoadFolder(pkg)) + + dir, err := pkg.Open(tt.in) r.NoError(err) defer dir.Close() @@ -138,7 +150,10 @@ func (s Suite) Test_HTTP_Dir_IndexHTML(t *testing.T) { func (s Suite) Test_HTTP_File(t *testing.T) { r := require.New(t) - cur, err := s.Current() + pkg, err := s.Make() + r.NoError(err) + + cur, err := pkg.Current() r.NoError(err) ip := cur.ImportPath @@ -152,12 +167,14 @@ func (s Suite) Test_HTTP_File(t *testing.T) { for _, tt := range table { s.Run(t, tt.in, func(st *testing.T) { - r := require.New(st) - r.NoError(s.LoadFolder()) + pkg, err := s.Make() + r.NoError(err) - dir, err := s.Open(tt.in) + r.NoError(s.LoadFolder(pkg)) + + dir, err := pkg.Open(tt.in) r.NoError(err) defer dir.Close() diff --git a/pkging/pkgtest/suite.go b/pkging/pkgtest/suite.go index 7ddc8f5..5863da5 100644 --- a/pkging/pkgtest/suite.go +++ b/pkging/pkgtest/suite.go @@ -20,12 +20,21 @@ const hart = "/easy/listening/grant.hart" const husker = "github.com/husker/du" type Suite struct { - pkging.Pkger + Name string + gen func() (pkging.Pkger, error) } -func NewSuite(yourpkging pkging.Pkger) (Suite, error) { +func (s Suite) Make() (pkging.Pkger, error) { + if s.gen == nil { + return nil, fmt.Errorf("missing generator function") + } + return s.gen() +} + +func NewSuite(name string, fn func() (pkging.Pkger, error)) (Suite, error) { suite := Suite{ - Pkger: yourpkging, + Name: name, + gen: fn, } return suite, nil } @@ -34,39 +43,60 @@ func (s Suite) Test(t *testing.T) { rv := reflect.ValueOf(s) rt := rv.Type() if rt.NumMethod() == 0 { - t.Fatalf("something went wrong wrong with %s %T", s, s) + t.Fatalf("something went wrong wrong with %s", s.Name) } for i := 0; i < rt.NumMethod(); i++ { m := rt.Method(i) if !strings.HasPrefix(m.Name, "Test_") { continue } + s.sub(t, m) } } +// func (s Suite) clone() (Suite, error) { +// if ns, ok := s.Pkger.(Newable); ok { +// pkg, err := ns.New() +// if err != nil { +// return s, err +// } +// s, err = NewSuite(pkg) +// if err != nil { +// return s, err +// } +// } +// if ns, ok := s.Pkger.(WithRootable); ok { +// dir, err := ioutil.TempDir("", "") +// if err != nil { +// return s, err +// } +// // defer opkg.RemoveAll(dir) +// +// pkg, err := ns.WithRoot(dir) +// if err != nil { +// return s, err +// } +// s, err = NewSuite(pkg) +// if err != nil { +// return s, err +// } +// } +// return s, nil +// } + func (s Suite) Run(t *testing.T, name string, fn func(t *testing.T)) { t.Run(name, func(st *testing.T) { - defer func() { - if err := recover(); err != nil { - st.Fatal(err) - } - }() - - cleaner := func() { - if err := s.Clean(); err != nil { - st.Fatal(err) - } - } - cleaner() - - defer cleaner() fn(st) }) } func (s Suite) sub(t *testing.T, m reflect.Method) { - name := fmt.Sprintf("%T/%s", s.Pkger, m.Name) + name := fmt.Sprintf("%s/%s", s.Name, m.Name) + // s, err := s.clone() + // if err != nil { + // t.Fatal(err) + // } s.Run(t, name, func(st *testing.T) { m.Func.Call([]reflect.Value{ reflect.ValueOf(s), @@ -75,26 +105,13 @@ func (s Suite) sub(t *testing.T, m reflect.Method) { }) } -func (s Suite) Clean() error { - pt, err := s.Parse("/") - if err != nil { - return err - } - - _ = pt - if err := s.RemoveAll(pt.Name); err != nil { - return err - } - - if _, err := s.Stat(pt.Name); err == nil { - return fmt.Errorf("expected %q to be, you know, not there any more", pt) - } - return nil -} - func (s Suite) Test_Create(t *testing.T) { r := require.New(t) - cur, err := s.Current() + + pkg, err := s.Make() + r.NoError(err) + + cur, err := pkg.Current() r.NoError(err) ip := cur.ImportPath @@ -104,22 +121,18 @@ func (s Suite) Test_Create(t *testing.T) { {in: mould}, {in: ":" + mould}, {in: ip + ":" + mould}, - {in: filepath.Dir(mould)}, - {in: ":" + filepath.Dir(mould)}, - {in: ip + ":" + filepath.Dir(mould)}, } for _, tt := range table { s.Run(t, tt.in, func(st *testing.T) { r := require.New(st) - pt, err := s.Parse(tt.in) + pt, err := pkg.Parse(tt.in) r.NoError(err) - r.NoError(s.RemoveAll(pt.String())) - r.NoError(s.MkdirAll(filepath.Dir(pt.Name), 0755)) + r.NoError(pkg.MkdirAll(filepath.Dir(pt.Name), 0755)) - f, err := s.Create(pt.Name) + f, err := pkg.Create(pt.Name) r.NoError(err) r.Equal(pt.Name, f.Name()) @@ -129,14 +142,18 @@ func (s Suite) Test_Create(t *testing.T) { r.Equal(pt.Name, fi.Name()) r.Equal(os.FileMode(0644), fi.Mode()) r.NotZero(fi.ModTime()) - r.NoError(s.RemoveAll(pt.String())) + r.NoError(pkg.RemoveAll(pt.String())) }) } } func (s Suite) Test_Create_No_MkdirAll(t *testing.T) { r := require.New(t) - cur, err := s.Current() + + pkg, err := s.Make() + r.NoError(err) + + cur, err := pkg.Current() r.NoError(err) ip := cur.ImportPath @@ -155,12 +172,13 @@ func (s Suite) Test_Create_No_MkdirAll(t *testing.T) { s.Run(t, tt.in, func(st *testing.T) { r := require.New(st) - pt, err := s.Parse(tt.in) + pkg, err := s.Make() r.NoError(err) - r.NoError(s.RemoveAll(pt.String())) + pt, err := pkg.Parse(tt.in) + r.NoError(err) - _, err = s.Create(pt.Name) + _, err = pkg.Create(pt.Name) r.Error(err) }) } @@ -169,7 +187,10 @@ func (s Suite) Test_Create_No_MkdirAll(t *testing.T) { func (s Suite) Test_Current(t *testing.T) { r := require.New(t) - info, err := s.Current() + pkg, err := s.Make() + r.NoError(err) + + info, err := pkg.Current() r.NoError(err) r.NotZero(info) } @@ -177,10 +198,13 @@ func (s Suite) Test_Current(t *testing.T) { func (s Suite) Test_Info(t *testing.T) { r := require.New(t) - cur, err := s.Current() + pkg, err := s.Make() r.NoError(err) - info, err := s.Info(cur.ImportPath) + cur, err := pkg.Current() + r.NoError(err) + + info, err := pkg.Info(cur.ImportPath) r.NoError(err) r.NotZero(info) @@ -188,7 +212,11 @@ func (s Suite) Test_Info(t *testing.T) { func (s Suite) Test_MkdirAll(t *testing.T) { r := require.New(t) - cur, err := s.Current() + + pkg, err := s.Make() + r.NoError(err) + + cur, err := pkg.Current() r.NoError(err) ip := cur.ImportPath @@ -207,21 +235,22 @@ func (s Suite) Test_MkdirAll(t *testing.T) { s.Run(t, tt.in, func(st *testing.T) { r := require.New(st) - pt, err := s.Parse(tt.in) + pkg, err := s.Make() r.NoError(err) - r.NoError(s.RemoveAll(pt.String())) + pt, err := pkg.Parse(tt.in) + r.NoError(err) dir := filepath.Dir(pt.Name) - r.NoError(s.MkdirAll(dir, 0755)) + r.NoError(pkg.MkdirAll(dir, 0755)) - fi, err := s.Stat(dir) + fi, err := pkg.Stat(dir) r.NoError(err) r.Equal(dir, fi.Name()) r.Equal(os.FileMode(0755), fi.Mode().Perm()) r.NotZero(fi.ModTime()) - r.NoError(s.RemoveAll(pt.String())) + r.NoError(pkg.RemoveAll(pt.String())) }) } } @@ -229,7 +258,10 @@ func (s Suite) Test_MkdirAll(t *testing.T) { func (s Suite) Test_Open_File(t *testing.T) { r := require.New(t) - cur, err := s.Current() + pkg, err := s.Make() + r.NoError(err) + + cur, err := pkg.Current() r.NoError(err) ip := cur.ImportPath @@ -244,20 +276,22 @@ func (s Suite) Test_Open_File(t *testing.T) { for _, tt := range table { s.Run(t, tt.in, func(st *testing.T) { - r := require.New(st) - pt, err := s.Parse(tt.in) + pkg, err := s.Make() r.NoError(err) - r.NoError(s.RemoveAll(pt.String())) - r.NoError(s.MkdirAll(filepath.Dir(pt.Name), 0755)) + pt, err := pkg.Parse(tt.in) + r.NoError(err) + + r.NoError(pkg.RemoveAll(pt.String())) + r.NoError(pkg.MkdirAll(filepath.Dir(pt.Name), 0755)) body := "!" + pt.String() - pkgutil.WriteFile(s, tt.in, []byte(body), 0644) + pkgutil.WriteFile(pkg, tt.in, []byte(body), 0644) - f, err := s.Open(tt.in) + f, err := pkg.Open(tt.in) r.NoError(err) r.Equal(pt.Name, f.Path().Name) @@ -265,7 +299,7 @@ func (s Suite) Test_Open_File(t *testing.T) { r.NoError(err) r.Equal(body, string(b)) - b, err = pkgutil.ReadFile(s, tt.in) + b, err = pkgutil.ReadFile(pkg, tt.in) r.NoError(err) r.Equal(body, string(b)) @@ -277,7 +311,10 @@ func (s Suite) Test_Open_File(t *testing.T) { func (s Suite) Test_Parse(t *testing.T) { r := require.New(t) - cur, err := s.Current() + pkg, err := s.Make() + r.NoError(err) + + cur, err := pkg.Current() r.NoError(err) ip := cur.ImportPath @@ -300,7 +337,7 @@ func (s Suite) Test_Parse(t *testing.T) { s.Run(t, tt.in, func(st *testing.T) { r := require.New(st) - pt, err := s.Parse(tt.in) + pt, err := pkg.Parse(tt.in) r.NoError(err) r.Equal(tt.exp, pt) }) @@ -310,7 +347,10 @@ func (s Suite) Test_Parse(t *testing.T) { func (s Suite) Test_Stat_Error(t *testing.T) { r := require.New(t) - cur, err := s.Current() + pkg, err := s.Make() + r.NoError(err) + + cur, err := pkg.Current() r.NoError(err) ip := cur.ImportPath @@ -330,12 +370,12 @@ func (s Suite) Test_Stat_Error(t *testing.T) { r := require.New(st) - pt, err := s.Parse(tt.in) + pt, err := pkg.Parse(tt.in) r.NoError(err) - r.NoError(s.RemoveAll(pt.String())) + r.NoError(pkg.RemoveAll(pt.String())) - _, err = s.Stat(tt.in) + _, err = pkg.Stat(tt.in) r.Error(err) }) } @@ -344,7 +384,10 @@ func (s Suite) Test_Stat_Error(t *testing.T) { func (s Suite) Test_Stat_Dir(t *testing.T) { r := require.New(t) - cur, err := s.Current() + pkg, err := s.Make() + r.NoError(err) + + cur, err := pkg.Current() r.NoError(err) dir := filepath.Dir(mould) @@ -364,13 +407,13 @@ func (s Suite) Test_Stat_Dir(t *testing.T) { r := require.New(st) - pt, err := s.Parse(tt.in) + pt, err := pkg.Parse(tt.in) r.NoError(err) - r.NoError(s.RemoveAll(pt.String())) + r.NoError(pkg.RemoveAll(pt.String())) - r.NoError(s.MkdirAll(pt.Name, 0755)) - info, err := s.Stat(tt.in) + r.NoError(pkg.MkdirAll(pt.Name, 0755)) + info, err := pkg.Stat(tt.in) r.NoError(err) r.Equal(pt.Name, info.Name()) }) @@ -380,7 +423,10 @@ func (s Suite) Test_Stat_Dir(t *testing.T) { func (s Suite) Test_Stat_File(t *testing.T) { r := require.New(t) - cur, err := s.Current() + pkg, err := s.Make() + r.NoError(err) + + cur, err := pkg.Current() r.NoError(err) ip := cur.ImportPath @@ -398,20 +444,23 @@ func (s Suite) Test_Stat_File(t *testing.T) { r := require.New(st) - pt, err := s.Parse(tt.in) + pkg, err := s.Make() r.NoError(err) - r.NoError(s.RemoveAll(pt.String())) - r.NoError(s.MkdirAll(filepath.Dir(pt.Name), 0755)) + pt, err := pkg.Parse(tt.in) + r.NoError(err) - f, err := s.Create(tt.in) + r.NoError(pkg.RemoveAll(pt.String())) + r.NoError(pkg.MkdirAll(filepath.Dir(pt.Name), 0755)) + + f, err := pkg.Create(tt.in) r.NoError(err) _, err = io.Copy(f, strings.NewReader("!"+pt.String())) r.NoError(err) r.NoError(f.Close()) - info, err := s.Stat(tt.in) + info, err := pkg.Stat(tt.in) r.NoError(err) r.Equal(pt.Name, info.Name()) }) @@ -421,7 +470,12 @@ func (s Suite) Test_Stat_File(t *testing.T) { // func (s Suite) Test_Walk(t *testing.T) { // panic("not implemented") // } + // // func (s Suite) Test_Remove(t *testing.T) { // panic("not implemented") // } +// +// func (s Suite) Test_RemoveAll(t *testing.T) { +// panic("not implemented") +// } diff --git a/pkging/pkgtest/util.go b/pkging/pkgtest/util.go index 5a71098..6386183 100644 --- a/pkging/pkgtest/util.go +++ b/pkging/pkgtest/util.go @@ -12,7 +12,11 @@ import ( func (s Suite) Test_Util_ReadFile(t *testing.T) { r := require.New(t) - cur, err := s.Current() + + pkg, err := s.Make() + r.NoError(err) + + cur, err := pkg.Current() r.NoError(err) ip := cur.ImportPath @@ -27,16 +31,18 @@ func (s Suite) Test_Util_ReadFile(t *testing.T) { for _, tt := range table { s.Run(t, tt.in, func(st *testing.T) { - r := require.New(st) - pt, err := s.Parse(tt.in) + pkg, err := s.Make() r.NoError(err) - r.NoError(s.RemoveAll(pt.String())) - r.NoError(s.MkdirAll(filepath.Dir(pt.Name), 0755)) + pt, err := pkg.Parse(tt.in) + r.NoError(err) - f, err := s.Create(tt.in) + r.NoError(pkg.RemoveAll(pt.String())) + r.NoError(pkg.MkdirAll(filepath.Dir(pt.Name), 0755)) + + f, err := pkg.Create(tt.in) r.NoError(err) body := "!" + pt.String() @@ -44,7 +50,7 @@ func (s Suite) Test_Util_ReadFile(t *testing.T) { r.NoError(err) r.NoError(f.Close()) - b, err := pkgutil.ReadFile(s, tt.in) + b, err := pkgutil.ReadFile(pkg, tt.in) r.NoError(err) r.Equal(body, string(b)) }) diff --git a/pkging/stdos/stdos.go b/pkging/stdos/stdos.go index 44ffa0e..2b65997 100644 --- a/pkging/stdos/stdos.go +++ b/pkging/stdos/stdos.go @@ -2,7 +2,6 @@ package stdos import ( "fmt" - "io/ioutil" "os" "path/filepath" "strings" @@ -107,14 +106,6 @@ func (f *Pkger) Parse(p string) (pkging.Path, error) { return f.paths.Parse(p) } -func (f *Pkger) ReadFile(s string) ([]byte, error) { - s, err := f.Abs(s) - if err != nil { - return nil, err - } - return ioutil.ReadFile(s) -} - func (f *Pkger) Stat(name string) (os.FileInfo, error) { pt, err := f.Parse(name) if err != nil { diff --git a/pkging/stdos/stdos_test.go b/pkging/stdos/stdos_test.go index e61edc0..09e31c1 100644 --- a/pkging/stdos/stdos_test.go +++ b/pkging/stdos/stdos_test.go @@ -1,24 +1,33 @@ package stdos import ( - "path/filepath" + "io/ioutil" "testing" + "github.com/markbates/pkger/pkging" "github.com/markbates/pkger/pkging/pkgtest" - "github.com/stretchr/testify/require" ) func Test_Pkger(t *testing.T) { - r := require.New(t) + suite, err := pkgtest.NewSuite("stdos", func() (pkging.Pkger, error) { + mypkging, err := New() + if err != nil { + return nil, err + } - mypkging, err := New() - r.NoError(err) + dir, err := ioutil.TempDir("", "stdos") + if err != nil { + return nil, err + } - mypkging.current.Dir = filepath.Join(mypkging.current.Dir, ".pkgtest") - mypkging.paths.Current = mypkging.current + mypkging.current.Dir = dir + mypkging.paths.Current = mypkging.current - suite, err := pkgtest.NewSuite(mypkging) - r.NoError(err) + return mypkging, nil + }) + if err != nil { + t.Fatal(err) + } suite.Test(t) } From 830ed679a868e19ffd08aa09abfdc593f081f323 Mon Sep 17 00:00:00 2001 From: Mark Bates Date: Fri, 20 Sep 2019 10:56:26 -0400 Subject: [PATCH 44/46] when you wake up feeling old --- pkging/mem/file.go | 151 +++++++++++++++++++------------------- pkging/mem/file_test.go | 52 +++++++++++++ pkging/mem/mem.go | 6 +- pkging/mem/mem_test.go | 5 +- pkging/pkgtest/http.go | 9 --- pkging/pkgtest/suite.go | 143 +++++++++++++++++++++++++++++++++--- pkging/stdos/file.go | 15 ++-- pkging/stdos/file_test.go | 29 ++++++++ pkging/stdos/stdos.go | 6 +- 9 files changed, 303 insertions(+), 113 deletions(-) create mode 100644 pkging/mem/file_test.go create mode 100644 pkging/stdos/file_test.go diff --git a/pkging/mem/file.go b/pkging/mem/file.go index c0c1548..a70d076 100644 --- a/pkging/mem/file.go +++ b/pkging/mem/file.go @@ -2,7 +2,6 @@ package mem import ( "bytes" - "encoding/json" "fmt" "io" "net/http" @@ -111,25 +110,25 @@ func (f File) String() string { return f.Path().String() } -func (f File) Format(st fmt.State, verb rune) { - switch verb { - case 'v': - if st.Flag('+') { - b, err := json.MarshalIndent(f, "", " ") - if err != nil { - fmt.Fprint(os.Stderr, err) - return - } - fmt.Fprint(st, string(b)) - return - } - fmt.Fprint(st, f.String()) - case 'q': - fmt.Fprintf(st, "%q", f.String()) - default: - fmt.Fprint(st, f.String()) - } -} +// func (f File) Format(st fmt.State, verb rune) { +// switch verb { +// case 'v': +// if st.Flag('+') { +// b, err := json.MarshalIndent(f, "", " ") +// if err != nil { +// fmt.Fprint(os.Stderr, err) +// return +// } +// fmt.Fprint(st, string(b)) +// return +// } +// fmt.Fprint(st, f.String()) +// case 'q': +// fmt.Fprintf(st, "%q", f.String()) +// default: +// fmt.Fprint(st, f.String()) +// } +// } func (f *File) Readdir(count int) ([]os.FileInfo, error) { var infos []os.FileInfo @@ -206,60 +205,60 @@ func (f *File) Open(name string) (http.File, error) { return di, nil } -func (f File) MarshalJSON() ([]byte, error) { - m := map[string]interface{}{ - "info": f.info, - "her": f.her, - "path": f.path, - "data": f.data, - "parent": f.parent, - } - return json.Marshal(m) -} +// func (f File) MarshalJSON() ([]byte, error) { +// m := map[string]interface{}{ +// "info": f.info, +// "her": f.her, +// "path": f.path, +// "data": f.data, +// "parent": f.parent, +// } +// return json.Marshal(m) +// } -func (f *File) UnmarshalJSON(b []byte) error { - m := map[string]json.RawMessage{} - if err := json.Unmarshal(b, &m); err != nil { - return err - } - - info, ok := m["info"] - if !ok { - return fmt.Errorf("missing info") - } - - f.info = &pkging.FileInfo{} - if err := json.Unmarshal(info, f.info); err != nil { - return err - } - - her, ok := m["her"] - if !ok { - return fmt.Errorf("missing her") - } - if err := json.Unmarshal(her, &f.her); err != nil { - return err - } - - path, ok := m["path"] - if !ok { - return fmt.Errorf("missing path") - } - if err := json.Unmarshal(path, &f.path); err != nil { - return err - } - - parent, ok := m["parent"] - if !ok { - return fmt.Errorf("missing parent") - } - if err := json.Unmarshal(parent, &f.parent); err != nil { - return err - } - - if err := json.Unmarshal(m["data"], &f.data); err != nil { - return err - } - - return nil -} +// func (f *File) UnmarshalJSON(b []byte) error { +// m := map[string]json.RawMessage{} +// if err := json.Unmarshal(b, &m); err != nil { +// return err +// } +// +// info, ok := m["info"] +// if !ok { +// return fmt.Errorf("missing info") +// } +// +// f.info = &pkging.FileInfo{} +// if err := json.Unmarshal(info, f.info); err != nil { +// return err +// } +// +// her, ok := m["her"] +// if !ok { +// return fmt.Errorf("missing her") +// } +// if err := json.Unmarshal(her, &f.her); err != nil { +// return err +// } +// +// path, ok := m["path"] +// if !ok { +// return fmt.Errorf("missing path") +// } +// if err := json.Unmarshal(path, &f.path); err != nil { +// return err +// } +// +// parent, ok := m["parent"] +// if !ok { +// return fmt.Errorf("missing parent") +// } +// if err := json.Unmarshal(parent, &f.parent); err != nil { +// return err +// } +// +// if err := json.Unmarshal(m["data"], &f.data); err != nil { +// return err +// } +// +// return nil +// } diff --git a/pkging/mem/file_test.go b/pkging/mem/file_test.go new file mode 100644 index 0000000..93c4e78 --- /dev/null +++ b/pkging/mem/file_test.go @@ -0,0 +1,52 @@ +package mem + +import ( + "io/ioutil" + "testing" + + "github.com/markbates/pkger/here" + "github.com/stretchr/testify/require" +) + +func Test_File_Seek(t *testing.T) { + r := require.New(t) + + info, err := here.Current() + r.NoError(err) + + pkg, err := New(info) + r.NoError(err) + + f, err := pkg.Create(":/wilco.band") + r.NoError(err) + + data := []byte("a shot in the arm") + f.Write(data) + r.NoError(f.Close()) + + f, err = pkg.Open(":/wilco.band") + r.NoError(err) + + b, err := ioutil.ReadAll(f) + r.NoError(err) + r.Equal(data, b) + + _, err = f.Seek(0, 0) + r.NoError(err) + + b, err = ioutil.ReadAll(f) + r.NoError(err) + r.Equal(data, b) + + b, err = ioutil.ReadAll(f) + r.NoError(err) + r.NotEqual(data, b) + + _, err = f.Seek(10, 0) + r.NoError(err) + + b, err = ioutil.ReadAll(f) + r.NoError(err) + r.NotEqual(data, b) + r.Equal([]byte("the arm"), b) +} diff --git a/pkging/mem/mem.go b/pkging/mem/mem.go index c1293f1..8f4ff97 100644 --- a/pkging/mem/mem.go +++ b/pkging/mem/mem.go @@ -29,6 +29,8 @@ func New(info here.Info) (*Pkger, error) { files: &maps.Files{}, current: info, } + f.infos.Store(info.ImportPath, info) + f.MkdirAll("/", 0755) return f, nil } @@ -105,6 +107,7 @@ func (fx *Pkger) RemoveAll(name string) error { } func (fx *Pkger) Create(name string) (pkging.File, error) { + fx.MkdirAll("/", 0755) pt, err := fx.Parse(name) if err != nil { return nil, err @@ -115,7 +118,8 @@ func (fx *Pkger) Create(name string) (pkging.File, error) { return nil, err } - if _, err := fx.Stat(filepath.Dir(pt.Name)); err != nil { + dir := filepath.Dir(pt.Name) + if _, err := fx.Stat(dir); err != nil { return nil, err } diff --git a/pkging/mem/mem_test.go b/pkging/mem/mem_test.go index 79effb2..724e767 100644 --- a/pkging/mem/mem_test.go +++ b/pkging/mem/mem_test.go @@ -15,13 +15,12 @@ func Test_Pkger(t *testing.T) { return nil, err } - wh, err := New(info) + pkg, err := New(info) if err != nil { return nil, err } - WithInfo(wh, info) - return wh, nil + return pkg, nil }) if err != nil { t.Fatal(err) diff --git a/pkging/pkgtest/http.go b/pkging/pkgtest/http.go index 2365bdf..d8c2747 100644 --- a/pkging/pkgtest/http.go +++ b/pkging/pkgtest/http.go @@ -12,24 +12,15 @@ import ( "github.com/stretchr/testify/require" ) -// examples/app -// ├── Dockerfile -// ├── Makefile -// ├── go.mod -// ├── go.sum // ├── main.go // ├── public // │   ├── images -// │   │   ├── mark-small.png // │   │   ├── mark.png -// │   │   ├── mark_250px.png -// │   │   └── mark_400px.png // │   └── index.html // └── templates // ├── a.txt // └── b // └── b.txt - func (s Suite) LoadFolder(pkg pkging.Pkger) error { files := []string{ "/main.go", diff --git a/pkging/pkgtest/suite.go b/pkging/pkgtest/suite.go index 5863da5..26b4577 100644 --- a/pkging/pkgtest/suite.go +++ b/pkging/pkgtest/suite.go @@ -67,7 +67,7 @@ func (s Suite) Test(t *testing.T) { // } // } // if ns, ok := s.Pkger.(WithRootable); ok { -// dir, err := ioutil.TempDir("", "") +// dir, err := ioutil.TempDir("") // if err != nil { // return s, err // } @@ -467,15 +467,134 @@ func (s Suite) Test_Stat_File(t *testing.T) { } } -// func (s Suite) Test_Walk(t *testing.T) { -// panic("not implemented") -// } +func (s Suite) Test_Walk(t *testing.T) { + r := require.New(t) -// -// func (s Suite) Test_Remove(t *testing.T) { -// panic("not implemented") -// } -// -// func (s Suite) Test_RemoveAll(t *testing.T) { -// panic("not implemented") -// } + pkg, err := s.Make() + r.NoError(err) + r.NoError(s.LoadFolder(pkg)) + + cur, err := pkg.Current() + r.NoError(err) + + ip := cur.ImportPath + + table := []struct { + in string + }{ + {in: ip}, + {in: "/"}, + {in: ":/"}, + {in: ip + ":/"}, + } + + for _, tt := range table { + s.Run(t, tt.in, func(st *testing.T) { + r := require.New(st) + var act []string + err := pkg.Walk(tt.in, func(path string, info os.FileInfo, err error) error { + if err != nil { + return err + } + act = append(act, path) + return nil + }) + r.NoError(err) + + exp := []string{ + "github.com/markbates/pkger:/", + "github.com/markbates/pkger:/main.go", + "github.com/markbates/pkger:/public", + "github.com/markbates/pkger:/public/images", + "github.com/markbates/pkger:/public/images/mark.png", + "github.com/markbates/pkger:/public/index.html", + "github.com/markbates/pkger:/templates", + "github.com/markbates/pkger:/templates/a.txt", + "github.com/markbates/pkger:/templates/b", + "github.com/markbates/pkger:/templates/b/b.txt", + } + r.Equal(exp, act) + }) + } + +} + +func (s Suite) Test_Remove(t *testing.T) { + r := require.New(t) + + pkg, err := s.Make() + r.NoError(err) + + cur, err := pkg.Current() + r.NoError(err) + + ip := cur.ImportPath + + table := []struct { + in string + }{ + {in: "/public/images/mark.png"}, + {in: ":/public/images/mark.png"}, + {in: ip + ":/public/images/mark.png"}, + } + + for _, tt := range table { + s.Run(t, tt.in, func(st *testing.T) { + r := require.New(st) + + pkg, err := s.Make() + r.NoError(err) + r.NoError(s.LoadFolder(pkg)) + + _, err = pkg.Stat(tt.in) + r.NoError(err) + + r.NoError(pkg.Remove(tt.in)) + + _, err = pkg.Stat(tt.in) + r.Error(err) + + r.Error(pkg.Remove("unknown")) + }) + } + +} + +func (s Suite) Test_RemoveAll(t *testing.T) { + r := require.New(t) + + pkg, err := s.Make() + r.NoError(err) + + cur, err := pkg.Current() + r.NoError(err) + + ip := cur.ImportPath + + table := []struct { + in string + }{ + {in: "/public"}, + {in: ":/public"}, + {in: ip + ":/public"}, + } + + for _, tt := range table { + s.Run(t, tt.in, func(st *testing.T) { + r := require.New(st) + + pkg, err := s.Make() + r.NoError(err) + r.NoError(s.LoadFolder(pkg)) + + _, err = pkg.Stat(tt.in) + r.NoError(err) + + r.NoError(pkg.RemoveAll(tt.in)) + + _, err = pkg.Stat(tt.in) + r.Error(err) + }) + } + +} diff --git a/pkging/stdos/file.go b/pkging/stdos/file.go index 303e697..249c277 100644 --- a/pkging/stdos/file.go +++ b/pkging/stdos/file.go @@ -20,11 +20,11 @@ type File struct { } func NewFile(fx pkging.Pkger, osf *os.File) (*File, error) { - pt, err := fx.Parse(osf.Name()) + name := osf.Name() + pt, err := fx.Parse(name) if err != nil { return nil, err } - info, err := osf.Stat() if err != nil { return nil, err @@ -97,15 +97,10 @@ func (f *File) Stat() (os.FileInfo, error) { return f.info, nil } - abs, err := f.Abs() + nf, err := NewFile(f.pkging, f.File) if err != nil { return nil, err } - - info, err := os.Stat(abs) - if err != nil { - return nil, err - } - f.info = pkging.NewFileInfo(info) - return info, nil + (*f) = *nf + return f.info, nil } diff --git a/pkging/stdos/file_test.go b/pkging/stdos/file_test.go new file mode 100644 index 0000000..90e0e5c --- /dev/null +++ b/pkging/stdos/file_test.go @@ -0,0 +1,29 @@ +package stdos + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func Test_File_Stat_No_Info(t *testing.T) { + r := require.New(t) + + pkg, err := New() + r.NoError(err) + + f, err := pkg.Open(":/pkging/stdos/file_test.go") + r.NoError(err) + defer f.Close() + + sf, ok := f.(*File) + r.True(ok) + + oi := sf.info + sf.info = nil + + info, err := sf.Stat() + r.NoError(err) + r.Equal(oi.Name(), info.Name()) + // r.Equal("", f.Name()) +} diff --git a/pkging/stdos/stdos.go b/pkging/stdos/stdos.go index 2b65997..f5cde28 100644 --- a/pkging/stdos/stdos.go +++ b/pkging/stdos/stdos.go @@ -43,13 +43,15 @@ func New() (*Pkger, error) { if err != nil { return nil, err } - return &Pkger{ + p := &Pkger{ infos: &maps.Infos{}, paths: &maps.Paths{ Current: info, }, current: info, - }, nil + } + p.infos.Store(info.ImportPath, info) + return p, nil } func (fx *Pkger) Create(name string) (pkging.File, error) { From fa998dbcb3227b68753fbafbef489f4a510224fa Mon Sep 17 00:00:00 2001 From: Mark Bates Date: Fri, 20 Sep 2019 11:16:57 -0400 Subject: [PATCH 45/46] camera's flash --- azure-pipelines.yml | 19 ++--- cmd/pkger/info.go | 5 +- cmd/pkger/pack.go | 16 ++-- cmd/pkger/serve.go | 9 ++- cmd/pkger/walk.go | 5 +- create.go | 36 --------- create_test.go | 55 ------------- dir.go | 55 ------------- examples/app/go.sum | 9 +++ file.go | 179 ------------------------------------------ file_info.go | 139 -------------------------------- file_test.go | 108 ------------------------- files_map.go | 144 --------------------------------- filter.go | 6 -- go.mod | 3 + go.sum | 9 +++ info.go | 17 ---- infos_map.go | 126 ----------------------------- json.go | 83 -------------------- open.go | 79 ------------------- open_test.go | 124 ----------------------------- parser/parser.go | 25 +++--- parser/parser_test.go | 13 +-- parser/visitor.go | 9 ++- path.go | 99 ----------------------- path_test.go | 52 ------------ paths_map.go | 123 ----------------------------- pkger.go | 126 +++++------------------------ pkger_test.go | 75 ------------------ stat.go | 14 ---- version.go | 4 - walk.go | 70 ----------------- 32 files changed, 93 insertions(+), 1743 deletions(-) delete mode 100644 create.go delete mode 100644 create_test.go delete mode 100644 dir.go delete mode 100644 file.go delete mode 100644 file_info.go delete mode 100644 file_test.go delete mode 100644 files_map.go delete mode 100644 filter.go delete mode 100644 info.go delete mode 100644 infos_map.go delete mode 100644 json.go delete mode 100644 open.go delete mode 100644 open_test.go delete mode 100644 path.go delete mode 100644 path_test.go delete mode 100644 paths_map.go delete mode 100644 pkger_test.go delete mode 100644 stat.go delete mode 100644 version.go delete mode 100644 walk.go diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 12956fd..108063a 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -1,4 +1,5 @@ variables: + GOPROXY: "https://proxy.golang.org" GOBIN: "$(GOPATH)/bin" # Go binaries path GOPATH: "$(system.defaultWorkingDirectory)/gopath" # Go workspace path modulePath: "$(GOPATH)/src/github.com/$(build.repository.name)" # Path to the module"s code @@ -9,12 +10,12 @@ jobs: vmImage: "vs2017-win2016" strategy: matrix: - go 1.11 (on): - go_version: "1.11.13" - GO111MODULE: "on" go 1.12 (on): go_version: "1.12.9" GO111MODULE: "on" + go 1.13 (on): + go_version: "1.13" + GO111MODULE: "on" steps: - template: azure-tests.yml @@ -23,12 +24,12 @@ jobs: vmImage: "macOS-10.13" strategy: matrix: - go 1.11 (on): - go_version: "1.11.13" - GO111MODULE: "on" go 1.12 (on): go_version: "1.12.9" GO111MODULE: "on" + go 1.13 (on): + go_version: "1.13" + GO111MODULE: "on" steps: - template: azure-tests.yml @@ -37,11 +38,11 @@ jobs: vmImage: "ubuntu-16.04" strategy: matrix: - go 1.11 (on): - go_version: "1.11.13" - GO111MODULE: "on" go 1.12 (on): go_version: "1.12.9" GO111MODULE: "on" + go 1.13 (on): + go_version: "1.13" + GO111MODULE: "on" steps: - template: azure-tests.yml diff --git a/cmd/pkger/info.go b/cmd/pkger/info.go index 3a6f5ad..986695c 100644 --- a/cmd/pkger/info.go +++ b/cmd/pkger/info.go @@ -5,6 +5,7 @@ import ( "fmt" "github.com/markbates/pkger" + "github.com/markbates/pkger/pkging" ) type infoCmd struct { @@ -44,12 +45,12 @@ func (f *infoCmd) Exec(args []string) error { return err } for _, ff := range files { - fmt.Println(pkger.NewFileInfo(ff)) + fmt.Println(pkging.NewFileInfo(ff)) } continue } - fmt.Println(pkger.NewFileInfo(fi)) + fmt.Println(pkging.NewFileInfo(fi)) } return nil diff --git a/cmd/pkger/pack.go b/cmd/pkger/pack.go index 652142a..b5a7e55 100644 --- a/cmd/pkger/pack.go +++ b/cmd/pkger/pack.go @@ -8,6 +8,7 @@ import ( "github.com/markbates/pkger" "github.com/markbates/pkger/parser" + "github.com/markbates/pkger/pkging" ) const outName = "pkged.go" @@ -24,12 +25,12 @@ func (e *packCmd) Name() string { } func (e *packCmd) Exec(args []string) error { - info, err := pkger.Stat() + info, err := pkger.Current() if err != nil { return err } - res, err := parser.Parse(info.Dir) + res, err := parser.Parse(info) if err != nil { return err } @@ -116,7 +117,7 @@ func (e *packCmd) Flags() *flag.FlagSet { return e.FlagSet } -func Package(out string, paths []pkger.Path) error { +func Package(out string, paths []pkging.Path) error { os.RemoveAll(out) f, err := os.Create(out) @@ -124,7 +125,7 @@ func Package(out string, paths []pkger.Path) error { return err } - c, err := pkger.Stat() + c, err := pkger.Current() if err != nil { return err } @@ -132,9 +133,10 @@ func Package(out string, paths []pkger.Path) error { fmt.Fprintf(f, "import \"github.com/markbates/pkger\"\n\n") fmt.Fprintf(f, "var _ = pkger.Unpack(`") - if err := pkger.Pack(f, paths); err != nil { - return err - } + // TODO + // if err := pkger.Pack(f, paths); err != nil { + // return err + // } fmt.Fprintf(f, "`)\n") diff --git a/cmd/pkger/serve.go b/cmd/pkger/serve.go index 474cc4f..f195e58 100644 --- a/cmd/pkger/serve.go +++ b/cmd/pkger/serve.go @@ -48,10 +48,11 @@ func (s *serveCmd) Exec(args []string) error { return err } - ex := append(defaultExcludes, s.excludes...) - if err := pkger.Exclude(f, ex...); err != nil { - return err - } + // TODO + // ex := append(defaultExcludes, s.excludes...) + // if err := pkger.Exclude(f, ex...); err != nil { + // return err + // } defer f.Close() fmt.Println(f.Path()) diff --git a/cmd/pkger/walk.go b/cmd/pkger/walk.go index 59c642c..907f041 100644 --- a/cmd/pkger/walk.go +++ b/cmd/pkger/walk.go @@ -8,7 +8,10 @@ import ( ) func walk(args []string) error { - err := pkger.Walk(".", func(path pkger.Path, info os.FileInfo) error { + err := pkger.Walk(".", func(path string, info os.FileInfo, err error) error { + if err != nil { + return err + } fmt.Println(path) return nil }) diff --git a/create.go b/create.go deleted file mode 100644 index 2adae16..0000000 --- a/create.go +++ /dev/null @@ -1,36 +0,0 @@ -package pkger - -import ( - "path/filepath" - "time" -) - -func Create(name string) (*File, error) { - pt, err := Parse(name) - if err != nil { - return nil, err - } - - her, err := Info(pt.Pkg) - if err != nil { - return nil, err - } - f := &File{ - path: pt, - her: her, - info: &FileInfo{ - name: pt.Name, - mode: 0666, - modTime: time.Now(), - virtual: true, - }, - } - - filesCache.Store(pt, f) - - dir := filepath.Dir(pt.Name) - if err := MkdirAll(dir, 0644); err != nil { - return nil, err - } - return f, nil -} diff --git a/create_test.go b/create_test.go deleted file mode 100644 index f53b023..0000000 --- a/create_test.go +++ /dev/null @@ -1,55 +0,0 @@ -package pkger - -import ( - "io" - "os" - "strings" - "testing" - - "github.com/stretchr/testify/require" -) - -func Test_Create(t *testing.T) { - r := require.New(t) - - f, err := Create("/hello.txt") - r.NoError(err) - r.NotNil(f) - - fi, err := f.Stat() - r.NoError(err) - - r.Equal("/hello.txt", fi.Name()) - r.Equal(os.FileMode(0666), fi.Mode()) - r.NotZero(fi.ModTime()) - - her := f.her - r.NotZero(her) - r.Equal("github.com/markbates/pkger", her.ImportPath) -} - -func Test_Create_Write(t *testing.T) { - r := require.New(t) - - f, err := Create("/hello.txt") - r.NoError(err) - r.NotNil(f) - - fi, err := f.Stat() - r.NoError(err) - r.Zero(fi.Size()) - - r.Equal("/hello.txt", fi.Name()) - - mt := fi.ModTime() - r.NotZero(mt) - - sz, err := io.Copy(f, strings.NewReader(radio)) - r.NoError(err) - r.Equal(int64(1381), sz) - - r.NoError(f.Close()) - r.Equal(int64(1381), fi.Size()) - r.NotZero(fi.ModTime()) - r.NotEqual(mt, fi.ModTime()) -} diff --git a/dir.go b/dir.go deleted file mode 100644 index 750fb11..0000000 --- a/dir.go +++ /dev/null @@ -1,55 +0,0 @@ -package pkger - -import ( - "os" - "path/filepath" - "time" -) - -func MkdirAll(p string, perm os.FileMode) error { - path, err := Parse(p) - if err != nil { - return err - } - root := path.Name - - cur, err := Stat() - if err != nil { - return err - } - for root != "" && root != "/" && root != "\\" { - pt := Path{ - Pkg: path.Pkg, - Name: root, - } - if _, ok := filesCache.Load(pt); ok { - root = filepath.Dir(root) - continue - } - f := &File{ - path: pt, - her: cur, - info: &FileInfo{ - name: pt.Name, - mode: 0666, - modTime: time.Now(), - virtual: true, - }, - } - - if err != nil { - return err - } - f.info.isDir = true - f.info.mode = perm - f.info.virtual = true - if err := f.Close(); err != nil { - return err - } - filesCache.Store(pt, f) - root = filepath.Dir(root) - } - - return nil - -} diff --git a/examples/app/go.sum b/examples/app/go.sum index 1945221..499657f 100644 --- a/examples/app/go.sum +++ b/examples/app/go.sum @@ -1,5 +1,12 @@ github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/markbates/errx v1.1.0/go.mod h1:PLa46Oex9KNbVDZhKel8v1OT7hD5JZ2eI7AHhA0wswc= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -8,5 +15,7 @@ github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJy github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/file.go b/file.go deleted file mode 100644 index a94bb18..0000000 --- a/file.go +++ /dev/null @@ -1,179 +0,0 @@ -package pkger - -import ( - "bytes" - "encoding/json" - "fmt" - "io" - "net/http" - "os" - "path/filepath" - "regexp" - "strings" - "time" - - "github.com/markbates/pkger/here" -) - -const timeFmt = time.RFC3339Nano - -var _ http.File = &File{} - -type File struct { - info *FileInfo - her here.Info - path Path - data []byte - parent Path - writer *bytes.Buffer - reader io.Reader - excludes []string -} - -func (f *File) Seek(offset int64, whence int) (int64, error) { - if sk, ok := f.reader.(io.Seeker); ok { - return sk.Seek(offset, whence) - } - return 0, nil -} - -func (f *File) Close() error { - defer func() { - f.reader = nil - f.writer = nil - }() - if f.reader != nil { - if c, ok := f.reader.(io.Closer); ok { - if err := c.Close(); err != nil { - return err - } - } - } - - if f.writer == nil { - return nil - } - - f.data = f.writer.Bytes() - - fi := f.info - fi.size = int64(len(f.data)) - fi.modTime = time.Now() - f.info = fi - return nil -} - -func (f *File) Read(p []byte) (int, error) { - if len(f.data) > 0 && f.reader == nil { - f.reader = bytes.NewReader(f.data) - } - - if f.reader != nil { - return f.reader.Read(p) - } - - of, err := f.her.Open(f.FilePath()) - if err != nil { - return 0, err - } - f.reader = of - return f.reader.Read(p) -} - -func (f *File) Write(b []byte) (int, error) { - if f.writer == nil { - f.writer = &bytes.Buffer{} - } - i, err := f.writer.Write(b) - return i, err -} - -func (f File) Info() here.Info { - return f.her -} - -func (f File) Stat() (os.FileInfo, error) { - if f.info == nil { - return nil, os.ErrNotExist - } - return f.info, nil -} - -func (f File) Name() string { - return f.info.Name() -} - -func (f File) FilePath() string { - return f.her.FilePath(f.Name()) -} - -func (f File) Path() Path { - return f.path -} - -func (f File) String() string { - return f.Path().String() -} - -func (f File) Format(st fmt.State, verb rune) { - switch verb { - case 'v': - if st.Flag('+') { - b, err := json.MarshalIndent(f, "", " ") - if err != nil { - fmt.Fprint(os.Stderr, err) - return - } - fmt.Fprint(st, string(b)) - return - } - fmt.Fprint(st, f.String()) - case 'q': - fmt.Fprintf(st, "%q", f.String()) - default: - fmt.Fprint(st, f.String()) - } -} - -func (f *File) Readdir(count int) ([]os.FileInfo, error) { - var infos []os.FileInfo - err := Walk(f.Name(), func(pt Path, info os.FileInfo) error { - if count > 0 && len(infos) == count { - return io.EOF - } - - for _, x := range f.excludes { - rx, err := regexp.Compile(x) - if err != nil { - return err - } - if rx.MatchString(pt.Name) { - if info.IsDir() { - return filepath.SkipDir - } - return nil - } - } - - if pt.Name == f.parent.Name { - return nil - } - if f.parent.Name != "/" { - info = WithName(strings.TrimPrefix(info.Name(), f.parent.Name), info) - } - infos = append(infos, info) - return nil - }) - - if err != nil { - if _, ok := err.(*os.PathError); ok { - return infos, nil - } - if err != io.EOF { - return nil, err - } - } - - return infos, nil - -} diff --git a/file_info.go b/file_info.go deleted file mode 100644 index 5eb30b2..0000000 --- a/file_info.go +++ /dev/null @@ -1,139 +0,0 @@ -package pkger - -import ( - "encoding/json" - "fmt" - "os" - "strings" - "time" -) - -type FileInfo struct { - name string - size int64 - mode os.FileMode - modTime time.Time - isDir bool - virtual bool - sys interface{} -} - -func (f *FileInfo) String() string { - b, _ := json.MarshalIndent(f, "", " ") - return string(b) -} - -func (f *FileInfo) MarshalJSON() ([]byte, error) { - return json.Marshal(map[string]interface{}{ - "name": f.name, - "size": f.size, - "mode": f.mode, - "modTime": f.modTime.Format(timeFmt), - "isDir": f.isDir, - "virtual": true, - "sys": f.sys, - }) -} - -func (f *FileInfo) UnmarshalJSON(b []byte) error { - m := map[string]interface{}{} - if err := json.Unmarshal(b, &m); err != nil { - return err - } - - var ok bool - - f.name, ok = m["name"].(string) - if !ok { - return fmt.Errorf("could not determine name %q", m["name"]) - } - - size, ok := m["size"].(float64) - if !ok { - return fmt.Errorf("could not determine size %q", m["size"]) - } - f.size = int64(size) - - mode, ok := m["mode"].(float64) - if !ok { - return fmt.Errorf("could not determine mode %q", m["mode"]) - } - f.mode = os.FileMode(mode) - - modTime, ok := m["modTime"].(string) - if !ok { - return fmt.Errorf("could not determine modTime %q", m["modTime"]) - } - t, err := time.Parse(timeFmt, modTime) - if err != nil { - return err - } - f.modTime = t - - f.isDir, ok = m["isDir"].(bool) - if !ok { - return fmt.Errorf("could not determine isDir %q", m["isDir"]) - } - f.sys = m["sys"] - f.virtual = true - return nil -} - -func (f *FileInfo) Name() string { - return f.name -} - -func (f *FileInfo) Size() int64 { - return f.size -} - -func (f *FileInfo) Mode() os.FileMode { - return f.mode -} - -func (f *FileInfo) ModTime() time.Time { - return f.modTime -} - -func (f *FileInfo) IsDir() bool { - return f.isDir -} - -func (f *FileInfo) Sys() interface{} { - return f.sys -} - -var _ os.FileInfo = &FileInfo{} - -func NewFileInfo(info os.FileInfo) *FileInfo { - fi := &FileInfo{ - name: cleanName(info.Name()), - size: info.Size(), - mode: info.Mode(), - modTime: info.ModTime(), - isDir: info.IsDir(), - sys: info.Sys(), - } - return fi -} - -func WithName(name string, info os.FileInfo) *FileInfo { - if ft, ok := info.(*FileInfo); ok { - ft.name = cleanName(name) - return ft - } - - fo := NewFileInfo(info) - fo.name = cleanName(name) - return fo -} - -func cleanName(s string) string { - if strings.Contains(s, "\\") { - s = strings.Replace(s, "\\", "/", -1) - } - if !strings.HasPrefix(s, "/") { - s = "/" + s - } - return s -} diff --git a/file_test.go b/file_test.go deleted file mode 100644 index 03527e3..0000000 --- a/file_test.go +++ /dev/null @@ -1,108 +0,0 @@ -package pkger - -import ( - "encoding/json" - "io" - "io/ioutil" - "strings" - "testing" - "time" - - "github.com/stretchr/testify/require" -) - -func Test_File_Open(t *testing.T) { - r := require.New(t) - - f, err := Open("/file_test.go") - r.NoError(err) - - r.Equal("/file_test.go", f.Name()) - - b, err := ioutil.ReadAll(f) - r.NoError(err) - r.Contains(string(b), "Test_File_Open") - r.NoError(f.Close()) -} - -func Test_File_Open_Dir(t *testing.T) { - r := require.New(t) - - f, err := Open("/cmd") - r.NoError(err) - - r.Equal("/cmd", f.Name()) - - r.NoError(f.Close()) -} - -func Test_File_Read_Memory(t *testing.T) { - r := require.New(t) - - f, err := Open("/file_test.go") - r.NoError(err) - f.data = []byte("hi!") - - r.Equal("/file_test.go", f.Name()) - - b, err := ioutil.ReadAll(f) - r.NoError(err) - r.Equal(string(b), "hi!") - r.NoError(f.Close()) -} - -func Test_File_Write(t *testing.T) { - r := require.New(t) - - f, err := Create("/hello.txt") - r.NoError(err) - r.NotNil(f) - - fi, err := f.Stat() - r.NoError(err) - r.Zero(fi.Size()) - - r.Equal("/hello.txt", fi.Name()) - - mt := fi.ModTime() - r.NotZero(mt) - - sz, err := io.Copy(f, strings.NewReader(radio)) - r.NoError(err) - r.Equal(int64(1381), sz) - - // because windows can't handle the time precisely - // enough, we have to *force* just a smidge of time - // to ensure the two ModTime's are different. - // i know, i hate it too. - time.Sleep(time.Millisecond) - r.NoError(f.Close()) - r.Equal(int64(1381), fi.Size()) - r.NotZero(fi.ModTime()) - r.NotEqual(mt, fi.ModTime()) -} - -func Test_File_JSON(t *testing.T) { - r := require.New(t) - - f, err := createFile("/radio.radio") - r.NoError(err) - r.NotNil(f) - - bi, err := f.Stat() - r.NoError(err) - - mj, err := json.Marshal(f) - r.NoError(err) - - f2 := &File{} - - r.NoError(json.Unmarshal(mj, f2)) - - ai, err := f2.Stat() - r.NoError(err) - - r.Equal(bi.Size(), ai.Size()) - - r.Equal(string(f.data), string(f2.data)) -} diff --git a/files_map.go b/files_map.go deleted file mode 100644 index 760a509..0000000 --- a/files_map.go +++ /dev/null @@ -1,144 +0,0 @@ -// Code generated by github.com/gobuffalo/mapgen. DO NOT EDIT. - -package pkger - -import ( - "encoding/json" - "fmt" - "sort" - "sync" -) - -// filesMap wraps sync.Map and uses the following types: -// key: Path -// value: *File -type filesMap struct { - data *sync.Map - once *sync.Once -} - -func (m *filesMap) Data() *sync.Map { - if m.once == nil { - m.once = &sync.Once{} - } - m.once.Do(func() { - if m.data == nil { - m.data = &sync.Map{} - } - }) - return m.data -} - -func (m *filesMap) MarshalJSON() ([]byte, error) { - var err error - mm := map[string]interface{}{} - m.Data().Range(func(key, value interface{}) bool { - var b []byte - b, err = json.Marshal(key) - if err != nil { - return false - } - mm[string(b)] = value - return true - }) - - if err != nil { - return nil, err - } - - return json.Marshal(mm) -} - -func (m *filesMap) UnmarshalJSON(b []byte) error { - mm := map[string]*File{} - - if err := json.Unmarshal(b, &mm); err != nil { - return err - } - for k, v := range mm { - var pt Path - if err := json.Unmarshal([]byte(k), &pt); err != nil { - return err - } - m.Store(pt, v) - } - return nil -} - -// Delete the key from the map -func (m *filesMap) Delete(key Path) { - m.Data().Delete(key) -} - -// Load the key from the map. -// Returns *File or bool. -// A false return indicates either the key was not found -// or the value is not of type *File -func (m *filesMap) Load(key Path) (*File, bool) { - i, ok := m.Data().Load(key) - if !ok { - return nil, false - } - s, ok := i.(*File) - return s, ok -} - -// LoadOrStore will return an existing key or -// store the value if not already in the map -func (m *filesMap) LoadOrStore(key Path, value *File) (*File, bool) { - i, _ := m.Data().LoadOrStore(key, value) - s, ok := i.(*File) - return s, ok -} - -// LoadOr will return an existing key or -// run the function and store the results -func (m *filesMap) LoadOr(key Path, fn func(*filesMap) (*File, bool)) (*File, bool) { - i, ok := m.Load(key) - if ok { - return i, ok - } - i, ok = fn(m) - if ok { - m.Store(key, i) - return i, ok - } - return i, false -} - -// Range over the *File values in the map -func (m *filesMap) Range(f func(key Path, value *File) bool) { - m.Data().Range(func(k, v interface{}) bool { - key, ok := k.(Path) - if !ok { - return false - } - value, ok := v.(*File) - if !ok { - return false - } - return f(key, value) - }) -} - -// Store a *File in the map -func (m *filesMap) Store(key Path, value *File) { - m.Data().Store(key, value) -} - -// Keys returns a list of keys in the map -func (m *filesMap) Keys() []Path { - var keys []Path - m.Range(func(key Path, value *File) bool { - keys = append(keys, key) - return true - }) - sort.Slice(keys, func(a, b int) bool { - return keys[a].String() <= keys[b].String() - }) - return keys -} - -func (m *filesMap) String() string { - return fmt.Sprintf("%v", m.Keys()) -} diff --git a/filter.go b/filter.go deleted file mode 100644 index a32a8a0..0000000 --- a/filter.go +++ /dev/null @@ -1,6 +0,0 @@ -package pkger - -func Exclude(fl *File, excludes ...string) error { - fl.excludes = append(fl.excludes, excludes...) - return nil -} diff --git a/go.mod b/go.mod index 086da1b..74293c9 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,9 @@ module github.com/markbates/pkger go 1.13 require ( + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/kr/pretty v0.1.0 // indirect github.com/markbates/errx v1.1.0 github.com/stretchr/testify v1.4.0 + gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect ) diff --git a/go.sum b/go.sum index fee900f..c6cc8bc 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,12 @@ github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/markbates/errx v1.1.0 h1:QDFeR+UP95dO12JgW+tgi2UVfo0V8YBHiUIOaeBPiEI= github.com/markbates/errx v1.1.0/go.mod h1:PLa46Oex9KNbVDZhKel8v1OT7hD5JZ2eI7AHhA0wswc= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= @@ -9,5 +16,7 @@ github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJy github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/info.go b/info.go deleted file mode 100644 index 4f52457..0000000 --- a/info.go +++ /dev/null @@ -1,17 +0,0 @@ -package pkger - -import "github.com/markbates/pkger/here" - -func Info(p string) (here.Info, error) { - info, ok := infosCache.Load(p) - if ok { - return info, nil - } - - info, err := here.Package(p) - if err != nil { - return info, err - } - infosCache.Store(p, info) - return info, nil -} diff --git a/infos_map.go b/infos_map.go deleted file mode 100644 index ed5f886..0000000 --- a/infos_map.go +++ /dev/null @@ -1,126 +0,0 @@ -// Code generated by github.com/markbates/pkger/mapgen. DO NOT EDIT. - -package pkger - -import ( - "encoding/json" - "fmt" - "sort" - "sync" - - "github.com/markbates/pkger/here" -) - -// infosMap wraps sync.Map and uses the following types: -// key: string -// value: here.Info -type infosMap struct { - data *sync.Map - once *sync.Once -} - -func (m *infosMap) Data() *sync.Map { - if m.once == nil { - m.once = &sync.Once{} - } - m.once.Do(func() { - if m.data == nil { - m.data = &sync.Map{} - } - }) - return m.data -} - -func (m *infosMap) MarshalJSON() ([]byte, error) { - mm := map[string]interface{}{} - m.data.Range(func(key, value interface{}) bool { - mm[fmt.Sprintf("%s", key)] = value - return true - }) - return json.Marshal(mm) -} - -func (m *infosMap) UnmarshalJSON(b []byte) error { - mm := map[string]here.Info{} - - if err := json.Unmarshal(b, &mm); err != nil { - return err - } - for k, v := range mm { - m.Store(k, v) - } - return nil -} - -// Delete the key from the map -func (m *infosMap) Delete(key string) { - m.Data().Delete(key) -} - -// Load the key from the map. -// Returns here.Info or bool. -// A false return indicates either the key was not found -// or the value is not of type here.Info -func (m *infosMap) Load(key string) (here.Info, bool) { - m.Data() - i, ok := m.data.Load(key) - if !ok { - return here.Info{}, false - } - s, ok := i.(here.Info) - return s, ok -} - -// LoadOrStore will return an existing key or -// store the value if not already in the map -func (m *infosMap) LoadOrStore(key string, value here.Info) (here.Info, bool) { - i, _ := m.Data().LoadOrStore(key, value) - s, ok := i.(here.Info) - return s, ok -} - -// LoadOr will return an existing key or -// run the function and store the results -func (m *infosMap) LoadOr(key string, fn func(*infosMap) (here.Info, bool)) (here.Info, bool) { - i, ok := m.Load(key) - if ok { - return i, ok - } - i, ok = fn(m) - if ok { - m.Store(key, i) - return i, ok - } - return i, false -} - -// Range over the here.Info values in the map -func (m *infosMap) Range(f func(key string, value here.Info) bool) { - m.Data().Range(func(k, v interface{}) bool { - key, ok := k.(string) - if !ok { - return false - } - value, ok := v.(here.Info) - if !ok { - return false - } - return f(key, value) - }) -} - -// Store a here.Info in the map -func (m *infosMap) Store(key string, value here.Info) { - m.Data().Store(key, value) -} - -// Keys returns a list of keys in the map -func (m *infosMap) Keys() []string { - var keys []string - m.Range(func(key string, value here.Info) bool { - keys = append(keys, key) - return true - }) - sort.Strings(keys) - return keys -} diff --git a/json.go b/json.go deleted file mode 100644 index 1b3a07e..0000000 --- a/json.go +++ /dev/null @@ -1,83 +0,0 @@ -package pkger - -import ( - "encoding/json" - "fmt" - "io/ioutil" - - "github.com/markbates/pkger/here" -) - -type jason struct { - Files *filesMap `json:"files"` - Infos *infosMap `json:"infos"` - Paths *pathsMap `json:"paths"` - CurrentInfo here.Info `json:"current_info"` -} - -func (f File) MarshalJSON() ([]byte, error) { - m := map[string]interface{}{} - m["info"] = f.info - m["her"] = f.her - m["path"] = f.path - m["data"] = f.data - m["parent"] = f.parent - if !f.info.virtual { - if len(f.data) == 0 && !f.info.IsDir() { - b, err := ioutil.ReadAll(&f) - if err != nil { - return nil, err - } - m["data"] = b - } - } - - return json.Marshal(m) -} - -func (f *File) UnmarshalJSON(b []byte) error { - m := map[string]json.RawMessage{} - if err := json.Unmarshal(b, &m); err != nil { - return err - } - - info, ok := m["info"] - if !ok { - return fmt.Errorf("missing info") - } - - f.info = &FileInfo{} - if err := json.Unmarshal(info, f.info); err != nil { - return err - } - - her, ok := m["her"] - if !ok { - return fmt.Errorf("missing her") - } - if err := json.Unmarshal(her, &f.her); err != nil { - return err - } - - path, ok := m["path"] - if !ok { - return fmt.Errorf("missing path") - } - if err := json.Unmarshal(path, &f.path); err != nil { - return err - } - - parent, ok := m["parent"] - if !ok { - return fmt.Errorf("missing parent") - } - if err := json.Unmarshal(parent, &f.parent); err != nil { - return err - } - - if err := json.Unmarshal(m["data"], &f.data); err != nil { - return err - } - - return nil -} diff --git a/open.go b/open.go deleted file mode 100644 index bc2b10d..0000000 --- a/open.go +++ /dev/null @@ -1,79 +0,0 @@ -package pkger - -import ( - "net/http" - "os" - "path" - "path/filepath" - "strings" -) - -func (f *File) Open(name string) (http.File, error) { - pt, err := Parse(name) - if err != nil { - return nil, err - } - - if pt == f.path { - return f, nil - } - - pt.Name = path.Join(f.Path().Name, pt.Name) - - di, err := Open(pt.String()) - if err != nil { - return nil, err - } - - fi, err := di.Stat() - if err != nil { - return nil, err - } - if fi.IsDir() { - di.parent = f.path - di.excludes = f.excludes - } - return di, nil -} - -func Open(name string) (*File, error) { - pt, err := Parse(name) - if err != nil { - return nil, err - } - - f, ok := filesCache.Load(pt) - if !ok { - return openDisk(pt) - } - nf := &File{ - info: WithName(f.info.Name(), f.info), - path: f.path, - data: f.data, - her: f.her, - } - - return nf, nil -} - -func openDisk(pt Path) (*File, error) { - info, err := Info(pt.Pkg) - if err != nil { - return nil, err - } - fp := info.Dir - if len(pt.Name) > 0 { - fp = filepath.Join(fp, pt.Name) - } - - fi, err := os.Stat(fp) - if err != nil { - return nil, err - } - f := &File{ - info: WithName(strings.TrimPrefix(pt.Name, "/"), NewFileInfo(fi)), - her: info, - path: pt, - } - return f, nil -} diff --git a/open_test.go b/open_test.go deleted file mode 100644 index 82545f2..0000000 --- a/open_test.go +++ /dev/null @@ -1,124 +0,0 @@ -package pkger - -// func Test_Open_File(t *testing.T) { -// r := require.New(t) -// -// f, err := Open(".") -// r.NoError(err) -// -// ts := httptest.NewServer(http.FileServer(f)) -// defer ts.Close() -// -// res, err := http.Get(ts.URL + "/cmd/pkger/main.go") -// r.NoError(err) -// r.Equal(200, res.StatusCode) -// -// b, err := ioutil.ReadAll(res.Body) -// r.NoError(err) -// r.Contains(string(b), "does not compute") -// -// r.NoError(f.Close()) -// } -// -// func Test_Open_Dir(t *testing.T) { -// r := require.New(t) -// -// f, err := Open("/") -// r.NoError(err) -// -// ts := httptest.NewServer(http.FileServer(f)) -// defer ts.Close() -// -// res, err := http.Get(ts.URL + "/cmd/pkger") -// r.NoError(err) -// r.Equal(200, res.StatusCode) -// -// b, err := ioutil.ReadAll(res.Body) -// r.NoError(err) -// r.Contains(string(b), `/cmd/pkger/main.go`) -// -// r.NoError(f.Close()) -// } -// -// func Test_Open_File_Memory(t *testing.T) { -// r := require.New(t) -// -// f, err := Create("/suit/case.txt") -// r.NoError(err) -// f.Write([]byte(radio)) -// r.NoError(f.Close()) -// -// r.Equal([]byte(radio), f.data) -// r.Contains(string(f.data), "I wanna bite the hand that feeds me") -// -// dir, err := Open("/") -// r.NoError(err) -// defer dir.Close() -// -// ts := httptest.NewServer(http.FileServer(dir)) -// defer ts.Close() -// -// res, err := http.Get(ts.URL + "/suit/case.txt") -// r.NoError(err) -// r.Equal(200, res.StatusCode) -// -// b, _ := ioutil.ReadAll(res.Body) -// // r.NoError(err) -// r.Contains(string(b), "I wanna bite the hand that feeds me") -// -// } -// -// func Test_Open_Dir_StripPrefix(t *testing.T) { -// r := require.New(t) -// -// ts := httptest.NewServer(http.StripPrefix("/assets/", http.FileServer(http.Dir("./testdata/public")))) -// defer ts.Close() -// -// res, err := http.Get(ts.URL + "/assets/radio.radio") -// r.NoError(err) -// r.Equal(200, res.StatusCode) -// -// b, _ := ioutil.ReadAll(res.Body) -// // r.NoError(err) -// r.Contains(string(b), "I wanna bite the hand that feeds me") -// -// res, err = http.Get(ts.URL + "/assets/") -// r.NoError(err) -// r.Equal(200, res.StatusCode) -// -// b, _ = ioutil.ReadAll(res.Body) -// // r.NoError(err) -// r.Contains(string(b), `radio.radio`) -// } -// -// func Test_Open_Dir_Memory_StripPrefix(t *testing.T) { -// r := require.New(t) -// -// err := MkdirAll("/testdata/public", 0755) -// r.NoError(err) -// -// dir, err := Open("/testdata/public") -// r.NoError(err) -// defer dir.Close() -// -// ts := httptest.NewServer(http.StripPrefix("/assets/", http.FileServer(dir))) -// defer ts.Close() -// -// res, err := http.Get(ts.URL + "/assets/radio.radio") -// r.NoError(err) -// r.Equal(200, res.StatusCode) -// -// b, _ := ioutil.ReadAll(res.Body) -// // r.NoError(err) -// r.Contains(string(b), "I wanna bite the hand that feeds me") -// -// res, err = http.Get(ts.URL + "/assets/") -// r.NoError(err) -// r.Equal(200, res.StatusCode) -// -// b, _ = ioutil.ReadAll(res.Body) -// // r.NoError(err) -// r.Contains(string(b), `/radio.radio`) -// r.NotContains(string(b), `/public`) -// r.NotContains(string(b), `//`) -// } diff --git a/parser/parser.go b/parser/parser.go index 3d85c94..7509fdf 100644 --- a/parser/parser.go +++ b/parser/parser.go @@ -9,20 +9,15 @@ import ( "github.com/markbates/pkger" "github.com/markbates/pkger/here" + "github.com/markbates/pkger/pkging" ) var DefaultIgnoredFolders = []string{".", "_", "vendor", "node_modules", "_fixtures", "testdata"} -func Parse(name string) (Results, error) { +func Parse(cur here.Info) (Results, error) { var r Results - c, err := pkger.Stat() - if err != nil { - return r, err - } - if name == "" { - name = c.ImportPath - } + name := cur.ImportPath pt, err := pkger.Parse(name) if err != nil { @@ -36,7 +31,7 @@ func Parse(name string) (Results, error) { return r, err } - m := map[pkger.Path]bool{} + m := map[pkging.Path]bool{} root := r.Path.Name if !strings.HasPrefix(root, string(filepath.Separator)) { @@ -117,7 +112,7 @@ func Parse(name string) (Results, error) { return nil }) - var found []pkger.Path + var found []pkging.Path for k := range m { if len(k.String()) == 0 { @@ -133,8 +128,8 @@ func Parse(name string) (Results, error) { return r, err } -func sourceFiles(pt pkger.Path) ([]pkger.Path, error) { - var res []pkger.Path +func sourceFiles(pt pkging.Path) ([]pkging.Path, error) { + var res []pkging.Path her, err := pkger.Info(pt.Pkg) @@ -177,7 +172,7 @@ func sourceFiles(pt pkger.Path) ([]pkger.Path, error) { n := strings.TrimPrefix(p, her.Dir) n = strings.Replace(n, "\\", "/", -1) - pt := pkger.Path{ + pt := pkging.Path{ Name: n, } res = append(res, pt) @@ -188,6 +183,6 @@ func sourceFiles(pt pkger.Path) ([]pkger.Path, error) { } type Results struct { - Paths []pkger.Path - Path pkger.Path + Paths []pkging.Path + Path pkging.Path } diff --git a/parser/parser_test.go b/parser/parser_test.go index 116d19a..5946b89 100644 --- a/parser/parser_test.go +++ b/parser/parser_test.go @@ -1,22 +1,23 @@ package parser import ( - "os" "path/filepath" "sort" "testing" + "github.com/markbates/pkger/here" "github.com/stretchr/testify/require" ) func Test_Parser(t *testing.T) { r := require.New(t) - pwd, err := os.Getwd() - r.NoError(err) - r.NoError(os.Chdir(filepath.Join("..", "examples", "app"))) - defer os.Chdir(pwd) - res, err := Parse("") + ch := filepath.Join("..", "examples", "app") + info := here.Info{ + Dir: ch, + ImportPath: "github.com/markbates/pkger/examples/app", + } + res, err := Parse(info) r.NoError(err) diff --git a/parser/visitor.go b/parser/visitor.go index 8d8a083..a7645cb 100644 --- a/parser/visitor.go +++ b/parser/visitor.go @@ -8,11 +8,12 @@ import ( "github.com/markbates/pkger" "github.com/markbates/pkger/here" + "github.com/markbates/pkger/pkging" ) type visitor struct { File string - Found map[pkger.Path]bool + Found map[pkging.Path]bool info here.Info errors []error } @@ -20,12 +21,12 @@ type visitor struct { func newVisitor(p string, info here.Info) (*visitor, error) { return &visitor{ File: p, - Found: map[pkger.Path]bool{}, + Found: map[pkging.Path]bool{}, info: info, }, nil } -func (v *visitor) Run() ([]pkger.Path, error) { +func (v *visitor) Run() ([]pkging.Path, error) { pf, err := parseFile(v.File) if err != nil { return nil, fmt.Errorf("%s: %v", v.File, err) @@ -33,7 +34,7 @@ func (v *visitor) Run() ([]pkger.Path, error) { ast.Walk(v, pf.Ast) - var found []pkger.Path + var found []pkging.Path for k := range v.Found { found = append(found, k) diff --git a/path.go b/path.go deleted file mode 100644 index 47cc7f0..0000000 --- a/path.go +++ /dev/null @@ -1,99 +0,0 @@ -package pkger - -import ( - "encoding/json" - "fmt" - "os" - "regexp" - "strings" -) - -type Path struct { - Pkg string `json:"pkg"` - Name string `json:"name"` -} - -func Parse(p string) (Path, error) { - p = strings.Replace(p, "\\", "/", -1) - pt, ok := pathsCache.Load(p) - if ok { - return pt, nil - } - if len(p) == 0 { - return build(p, "", "") - } - - res := pathrx.FindAllStringSubmatch(p, -1) - if len(res) == 0 { - return pt, fmt.Errorf("could not parse %q", p) - } - - matches := res[0] - - if len(matches) != 4 { - return pt, fmt.Errorf("could not parse %q", p) - } - - return build(p, matches[1], matches[3]) -} - -func (p Path) String() string { - if p.Name == "" { - p.Name = "/" - } - return fmt.Sprintf("%s:%s", p.Pkg, p.Name) -} - -func (p Path) Format(st fmt.State, verb rune) { - switch verb { - case 'v': - if st.Flag('+') { - b, err := json.MarshalIndent(p, "", " ") - if err != nil { - fmt.Fprint(os.Stderr, err) - return - } - fmt.Fprint(st, string(b)) - return - } - fmt.Fprint(st, p.String()) - case 'q': - fmt.Fprintf(st, "%q", p.String()) - default: - fmt.Fprint(st, p.String()) - } -} - -var pathrx = regexp.MustCompile("([^:]+)(:(/.+))?") - -func build(p, pkg, name string) (Path, error) { - pt := Path{ - Pkg: pkg, - Name: name, - } - - current, err := Stat() - if err != nil { - return pt, err - } - - if strings.HasPrefix(pt.Pkg, "/") || len(pt.Pkg) == 0 { - pt.Name = pt.Pkg - pt.Pkg = current.ImportPath - } - - if len(pt.Name) == 0 { - pt.Name = "/" - } - - if pt.Pkg == pt.Name { - pt.Pkg = current.ImportPath - pt.Name = "/" - } - - if !strings.HasPrefix(pt.Name, "/") { - pt.Name = "/" + pt.Name - } - pathsCache.Store(p, pt) - return pt, nil -} diff --git a/path_test.go b/path_test.go deleted file mode 100644 index 5366177..0000000 --- a/path_test.go +++ /dev/null @@ -1,52 +0,0 @@ -package pkger - -import ( - "testing" - - "github.com/stretchr/testify/require" -) - -func Test_Path_String(t *testing.T) { - table := []struct { - in Path - out string - }{ - {in: Path{}, out: ":/"}, - {in: Path{Pkg: curPkg}, out: curPkg + ":/"}, - {in: Path{Pkg: curPkg, Name: "/foo.go"}, out: curPkg + ":/foo.go"}, - {in: Path{Name: "/foo.go"}, out: ":/foo.go"}, - {in: Path{Pkg: "github.com/markbates/pkger/internal/examples/app"}, out: "github.com/markbates/pkger/internal/examples/app:/"}, - } - - for _, tt := range table { - t.Run(tt.in.String(), func(st *testing.T) { - r := require.New(st) - r.Equal(tt.out, tt.in.String()) - }) - } -} -func Test_Parse(t *testing.T) { - table := []struct { - in string - out Path - }{ - {in: curPkg, out: Path{Pkg: curPkg, Name: "/"}}, - {in: curPkg + ":/foo.go", out: Path{Pkg: curPkg, Name: "/foo.go"}}, - {in: "/paths/parse_test.go", out: Path{Pkg: curPkg, Name: "/paths/parse_test.go"}}, - {in: `\windows\path.go`, out: Path{Pkg: curPkg, Name: "/windows/path.go"}}, - {in: "", out: Path{Pkg: curPkg, Name: "/"}}, - {in: "github.com/markbates/pkger/internal/examples/app", out: Path{Pkg: "github.com/markbates/pkger/internal/examples/app", Name: "/"}}, - } - - for _, tt := range table { - t.Run(tt.in, func(st *testing.T) { - r := require.New(st) - - pt, err := Parse(tt.in) - r.NoError(err) - - r.Equal(tt.out.Pkg, pt.Pkg) - r.Equal(tt.out.Name, pt.Name) - }) - } -} diff --git a/paths_map.go b/paths_map.go deleted file mode 100644 index e0fcb0f..0000000 --- a/paths_map.go +++ /dev/null @@ -1,123 +0,0 @@ -// Code generated by github.com/gobuffalo/mapgen. DO NOT EDIT. - -package pkger - -import ( - "encoding/json" - "fmt" - "sort" - "sync" -) - -// pathsMap wraps sync.Map and uses the following types: -// key: string -// value: Path -type pathsMap struct { - data *sync.Map - once *sync.Once -} - -func (m *pathsMap) Data() *sync.Map { - if m.once == nil { - m.once = &sync.Once{} - } - m.once.Do(func() { - if m.data == nil { - m.data = &sync.Map{} - } - }) - return m.data -} - -func (m *pathsMap) MarshalJSON() ([]byte, error) { - mm := map[string]interface{}{} - m.Data().Range(func(key, value interface{}) bool { - mm[fmt.Sprintf("%s", key)] = value - return true - }) - return json.Marshal(mm) -} - -func (m *pathsMap) UnmarshalJSON(b []byte) error { - mm := map[string]Path{} - - if err := json.Unmarshal(b, &mm); err != nil { - return err - } - for k, v := range mm { - m.Store(k, v) - } - return nil -} - -// Delete the key from the map -func (m *pathsMap) Delete(key string) { - m.Data().Delete(key) -} - -// Load the key from the map. -// Returns Path or bool. -// A false return indicates either the key was not found -// or the value is not of type Path -func (m *pathsMap) Load(key string) (Path, bool) { - i, ok := m.Data().Load(key) - if !ok { - return Path{}, false - } - s, ok := i.(Path) - return s, ok -} - -// LoadOrStore will return an existing key or -// store the value if not already in the map -func (m *pathsMap) LoadOrStore(key string, value Path) (Path, bool) { - i, _ := m.Data().LoadOrStore(key, value) - s, ok := i.(Path) - return s, ok -} - -// LoadOr will return an existing key or -// run the function and store the results -func (m *pathsMap) LoadOr(key string, fn func(*pathsMap) (Path, bool)) (Path, bool) { - i, ok := m.Load(key) - if ok { - return i, ok - } - i, ok = fn(m) - if ok { - m.Store(key, i) - return i, ok - } - return i, false -} - -// Range over the Path values in the map -func (m *pathsMap) Range(f func(key string, value Path) bool) { - m.Data().Range(func(k, v interface{}) bool { - key, ok := k.(string) - if !ok { - return false - } - value, ok := v.(Path) - if !ok { - return false - } - return f(key, value) - }) -} - -// Store a Path in the map -func (m *pathsMap) Store(key string, value Path) { - m.Data().Store(key, value) -} - -// Keys returns a list of keys in the map -func (m *pathsMap) Keys() []string { - var keys []string - m.Range(func(key string, value Path) bool { - keys = append(keys, key) - return true - }) - sort.Strings(keys) - return keys -} diff --git a/pkger.go b/pkger.go index 58a69d2..326e3ac 100644 --- a/pkger.go +++ b/pkger.go @@ -1,117 +1,29 @@ package pkger import ( - "bytes" - "compress/gzip" - "encoding/hex" - "encoding/json" - "fmt" - "io" - "io/ioutil" "log" - "sync" - "github.com/markbates/pkger/here" + "github.com/markbates/pkger/pkging" + "github.com/markbates/pkger/pkging/stdos" ) -var filesCache = &filesMap{} -var infosCache = &infosMap{} -var pathsCache = &pathsMap{} -var curOnce = &sync.Once{} -var currentInfo here.Info - -var packed bool - -var packMU = &sync.RWMutex{} - -func ReadFile(s string) ([]byte, error) { - f, err := Open(s) +var current = func() pkging.Pkger { + n, err := stdos.New() if err != nil { - return nil, err + log.Fatal(err) } - defer f.Close() - return ioutil.ReadAll(f) -} + return n +}() -func Unpack(ind string) error { - packed = true - packMU.Lock() - defer packMU.Unlock() - b, err := hex.DecodeString(ind) - if err != nil { - log.Fatal("hex.DecodeString", err) - return err - } - - gz, err := gzip.NewReader(bytes.NewReader(b)) - if err != nil { - log.Fatal("gzip.NewReader", err) - return err - } - defer gz.Close() - - var jay jason - if err := json.NewDecoder(gz).Decode(&jay); err != nil { - return err - } - jay.Files.Range(func(key Path, value *File) bool { - filesCache.Store(key, value) - return true - }) - jay.Infos.Range(func(key string, value here.Info) bool { - infosCache.Store(key, value) - return true - }) - jay.Paths.Range(func(key string, value Path) bool { - pathsCache.Store(key, value) - return true - }) - currentInfo = jay.CurrentInfo - return nil -} - -func Pack(out io.Writer, paths []Path) error { - packMU.RLock() - defer packMU.RUnlock() - bb := &bytes.Buffer{} - gz := gzip.NewWriter(bb) - defer gz.Close() - - for _, p := range paths { - f, err := Open(p.String()) - if err != nil { - return err - } - - fi, err := f.Stat() - if err != nil { - return err - } - if fi.IsDir() { - filesCache.Store(p, f) - f.Close() - continue - } - - filesCache.Store(p, f) - f.Close() - - } - - jay := jason{ - Files: filesCache, - Infos: infosCache, - Paths: pathsCache, - CurrentInfo: currentInfo, - } - - if err := json.NewEncoder(gz).Encode(jay); err != nil { - return err - } - if err := gz.Close(); err != nil { - return err - } - s := hex.EncodeToString(bb.Bytes()) - _, err := fmt.Fprint(out, s) - return err -} +var Abs = current.Abs +var AbsPath = current.AbsPath +var Create = current.Create +var Current = current.Current +var Info = current.Info +var MkdirAll = current.MkdirAll +var Open = current.Open +var Parse = current.Parse +var Remove = current.Remove +var RemoveAll = current.RemoveAll +var Stat = current.Stat +var Walk = current.Walk diff --git a/pkger_test.go b/pkger_test.go deleted file mode 100644 index aa6c240..0000000 --- a/pkger_test.go +++ /dev/null @@ -1,75 +0,0 @@ -package pkger - -import ( - "io" - "strings" - "testing" - - "github.com/stretchr/testify/require" -) - -const curPkg = "github.com/markbates/pkger" - -func Test_ReadFile(t *testing.T) { - r := require.New(t) - b, err := ReadFile("/LICENSE") - r.NoError(err) - r.Contains(string(b), "MIT") -} - -func createFile(p string, body ...string) (*File, error) { - if len(body) == 0 { - body = append(body, radio) - } - - f, err := Create(p) - if err != nil { - return nil, err - } - - _, err = io.Copy(f, strings.NewReader(strings.Join(body, "\n\n"))) - if err != nil { - return nil, err - } - - if err := f.Close(); err != nil { - return nil, err - } - return f, nil -} - -const radio = `I was tuning in the shine on the late night dial -Doing anything my radio advised -With every one of those late night stations -Playing songs bringing tears to my eyes -I was seriously thinking about hiding the receiver -When the switch broke 'cause it's old -They're saying things that I can hardly believe -They really think we're getting out of control -Radio is a sound salvation -Radio is cleaning up the nation -They say you better listen to the voice of reason -But they don't give you any choice 'cause they think that it's treason -So you had better do as you are told -You better listen to the radio -I wanna bite the hand that feeds me -I wanna bite that hand so badly -I want to make them wish they'd never seen me -Some of my friends sit around every evening -And they worry about the times ahead -But everybody else is overwhelmed by indifference -And the promise of an early bed -You either shut up or get cut up; they don't wanna hear about it -It's only inches on the reel-to-reel -And the radio is in the hands of such a lot of fools -Tryin' to anesthetize the way that you feel -Radio is a sound salvation -Radio is cleaning up the nation -They say you better listen to the voice of reason -But they don't give you any choice 'cause they think that it's treason -So you had better do as you are told -You better listen to the radio -Wonderful radio -Marvelous radio -Wonderful radio -Radio, radio` diff --git a/stat.go b/stat.go deleted file mode 100644 index d76c264..0000000 --- a/stat.go +++ /dev/null @@ -1,14 +0,0 @@ -package pkger - -import "github.com/markbates/pkger/here" - -func Stat() (here.Info, error) { - var err error - curOnce.Do(func() { - if currentInfo.IsZero() { - currentInfo, err = here.Current() - } - }) - - return currentInfo, err -} diff --git a/version.go b/version.go deleted file mode 100644 index 6a02283..0000000 --- a/version.go +++ /dev/null @@ -1,4 +0,0 @@ -package pkger - -// Version of pkger -const Version = "v0.0.1" diff --git a/walk.go b/walk.go deleted file mode 100644 index 1f027e8..0000000 --- a/walk.go +++ /dev/null @@ -1,70 +0,0 @@ -package pkger - -import ( - "fmt" - "os" - "path/filepath" - "strings" - - "github.com/markbates/pkger/here" -) - -type WalkFunc func(Path, os.FileInfo) error - -func Walk(p string, wf WalkFunc) error { - pt, err := Parse(p) - if err != nil { - return err - } - - filesCache.Range(func(k Path, v *File) bool { - if k.Pkg != pt.Pkg { - return true - } - if !strings.HasPrefix(k.Name, pt.Name) { - return true - } - if err = wf(k, v.info); err != nil { - if err == filepath.SkipDir { - return true - } - return false - } - return true - }) - - if packed { - return nil - } - - var info here.Info - if pt.Pkg == "." { - info, err = Stat() - if err != nil { - return err - } - pt.Pkg = info.ImportPath - } - - if info.IsZero() { - info, err = Info(pt.Pkg) - if err != nil { - return fmt.Errorf("%s: %s", pt, err) - } - } - fp := filepath.Join(info.Dir, pt.Name) - err = filepath.Walk(fp, func(path string, fi os.FileInfo, err error) error { - if err != nil { - return err - } - - path = strings.TrimPrefix(path, info.Dir) - pt, err := Parse(fmt.Sprintf("%s:%s", pt.Pkg, path)) - if err != nil { - return err - } - return wf(pt, WithName(path, NewFileInfo(fi))) - }) - - return err -} From 0e3411706a48c5718a2b0d3e64127a05b09091bd Mon Sep 17 00:00:00 2001 From: Mark Bates Date: Fri, 20 Sep 2019 15:40:55 -0400 Subject: [PATCH 46/46] automatic, as in buffalo --- Makefile | 2 +- examples/extfile/go.mod | 5 ++++- examples/httpserver/go.mod | 5 ++++- examples/walk/go.mod | 5 ++++- internal/maps/paths.go | 7 +++++-- pkging/pkgtest/suite.go | 7 +++++-- 6 files changed, 23 insertions(+), 8 deletions(-) diff --git a/Makefile b/Makefile index b728e38..94018ac 100644 --- a/Makefile +++ b/Makefile @@ -13,7 +13,7 @@ build: tidy make tidy test: tidy - $(GO_BIN) test -cover -tags ${TAGS} -timeout 5s -race ./... + $(GO_BIN) test -cover -tags ${TAGS} -timeout 5s ./... make tidy cov: diff --git a/examples/extfile/go.mod b/examples/extfile/go.mod index d2d00ec..1fc766a 100644 --- a/examples/extfile/go.mod +++ b/examples/extfile/go.mod @@ -2,4 +2,7 @@ module github.com/markbates/pkger/examples/extfile go 1.12 -require github.com/markbates/pkger v0.0.0-20190830024022-c5e3a7de4d41 +require github.com/markbates/pkger v0.0.0 + +replace github.com/markbates/pkger => ../../ + diff --git a/examples/httpserver/go.mod b/examples/httpserver/go.mod index 7c40bee..c79a7e0 100644 --- a/examples/httpserver/go.mod +++ b/examples/httpserver/go.mod @@ -2,4 +2,7 @@ module github.com/markbates/pkger/examples/httpserver go 1.12 -require github.com/markbates/pkger v0.0.0-20190830024022-c5e3a7de4d41 +require github.com/markbates/pkger v0.0.0 + +replace github.com/markbates/pkger => ../../ + diff --git a/examples/walk/go.mod b/examples/walk/go.mod index e91a1ae..5f77686 100644 --- a/examples/walk/go.mod +++ b/examples/walk/go.mod @@ -2,4 +2,7 @@ module github.com/markbates/pkger/examples/walk go 1.12 -require github.com/markbates/pkger v0.0.0-20190830024022-c5e3a7de4d41 +require github.com/markbates/pkger v0.0.0 + +replace github.com/markbates/pkger => ../../ + diff --git a/internal/maps/paths.go b/internal/maps/paths.go index 969df6b..3dff246 100644 --- a/internal/maps/paths.go +++ b/internal/maps/paths.go @@ -1,10 +1,9 @@ -// Code generated by github.com/gobuffalo/mapgen. DO NOT EDIT. - package maps import ( "encoding/json" "fmt" + "path/filepath" "regexp" "sort" "strings" @@ -106,6 +105,10 @@ func (m *Paths) Keys() []string { } func (m *Paths) Parse(p string) (pkging.Path, error) { + p = strings.TrimSpace(p) + p = filepath.Clean(p) + p = strings.TrimPrefix(p, m.Current.Dir) + p = strings.Replace(p, "\\", "/", -1) p = strings.TrimSpace(p) diff --git a/pkging/pkgtest/suite.go b/pkging/pkgtest/suite.go index 26b4577..66af56f 100644 --- a/pkging/pkgtest/suite.go +++ b/pkging/pkgtest/suite.go @@ -7,6 +7,7 @@ import ( "os" "path/filepath" "reflect" + "runtime" "strings" "testing" @@ -138,9 +139,9 @@ func (s Suite) Test_Create(t *testing.T) { fi, err := f.Stat() r.NoError(err) + r.NoError(f.Close()) r.Equal(pt.Name, fi.Name()) - r.Equal(os.FileMode(0644), fi.Mode()) r.NotZero(fi.ModTime()) r.NoError(pkg.RemoveAll(pt.String())) }) @@ -247,8 +248,10 @@ func (s Suite) Test_MkdirAll(t *testing.T) { fi, err := pkg.Stat(dir) r.NoError(err) + if runtime.GOOS == "windows" { + dir = strings.Replace(dir, "\\", "/", -1) + } r.Equal(dir, fi.Name()) - r.Equal(os.FileMode(0755), fi.Mode().Perm()) r.NotZero(fi.ModTime()) r.NoError(pkg.RemoveAll(pt.String())) })