mirror of https://github.com/markbates/pkger.git
porch
This commit is contained in:
parent
c129ccbfe0
commit
d453473dc0
|
@ -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
|
|
||||||
}
|
|
|
@ -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`
|
|
|
@ -152,6 +152,10 @@ func (f *File) Readdir(count int) ([]os.FileInfo, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
info = pkging.WithName(strings.TrimPrefix(info.Name(), f.parent.Name), info)
|
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)
|
infos = append(infos, info)
|
||||||
if info.IsDir() && path != root {
|
if info.IsDir() && path != root {
|
||||||
return filepath.SkipDir
|
return filepath.SkipDir
|
||||||
|
@ -205,3 +209,61 @@ func (f *File) Open(name string) (http.File, error) {
|
||||||
}
|
}
|
||||||
return di, nil
|
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
|
||||||
|
}
|
||||||
|
|
|
@ -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())
|
|
||||||
// }
|
|
|
@ -1 +0,0 @@
|
||||||
package mem
|
|
|
@ -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), `<a href="/public/images/mark.png">/public/images/mark.png</a>`)
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// 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), `<a href="/mark.png">/mark.png</a>`)
|
|
||||||
// r.NotContains(string(b), `/public`)
|
|
||||||
// r.NotContains(string(b), `/images`)
|
|
||||||
// r.NotContains(string(b), `/go.mod`)
|
|
||||||
// }
|
|
|
@ -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
|
|
||||||
}
|
|
|
@ -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))
|
|
||||||
// }
|
|
|
@ -3,7 +3,9 @@ package mem
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/markbates/pkger/here"
|
"github.com/markbates/pkger/here"
|
||||||
"github.com/markbates/pkger/internal/maps"
|
"github.com/markbates/pkger/internal/maps"
|
||||||
|
@ -95,3 +97,166 @@ func (fx *Pkger) RemoveAll(name string) error {
|
||||||
|
|
||||||
return nil
|
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
|
||||||
|
}
|
||||||
|
|
|
@ -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
|
|
||||||
|
|
||||||
}
|
|
|
@ -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())
|
|
||||||
}
|
|
|
@ -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
|
|
||||||
}
|
|
|
@ -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)
|
|
||||||
// }
|
|
|
@ -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)
|
|
||||||
}
|
|
|
@ -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())
|
|
||||||
// }
|
|
|
@ -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
|
|
||||||
}
|
|
|
@ -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)
|
|
||||||
// }
|
|
|
@ -40,22 +40,22 @@ func (s Suite) Test_File_Info(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s Suite) Test_File_Read(t *testing.T) {
|
// func (s Suite) Test_File_Read(t *testing.T) {
|
||||||
panic("not implemented")
|
// panic("not implemented")
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
func (s Suite) Test_File_Readdir(t *testing.T) {
|
// func (s Suite) Test_File_Readdir(t *testing.T) {
|
||||||
panic("not implemented")
|
// panic("not implemented")
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
func (s Suite) Test_File_Seek(t *testing.T) {
|
// func (s Suite) Test_File_Seek(t *testing.T) {
|
||||||
panic("not implemented")
|
// panic("not implemented")
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
func (s Suite) Test_File_Stat(t *testing.T) {
|
// func (s Suite) Test_File_Stat(t *testing.T) {
|
||||||
panic("not implemented")
|
// panic("not implemented")
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
func (s Suite) Test_File_Write(t *testing.T) {
|
// func (s Suite) Test_File_Write(t *testing.T) {
|
||||||
panic("not implemented")
|
// panic("not implemented")
|
||||||
}
|
// }
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/markbates/pkger/pkging/pkgutil"
|
"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) {
|
// func (s Suite) Test_HTTP_File_Memory(t *testing.T) {
|
||||||
// r := require.New(t)
|
// r := require.New(t)
|
||||||
//
|
//
|
||||||
|
|
|
@ -18,24 +18,7 @@ type File struct {
|
||||||
pkging pkging.Pkger
|
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) {
|
func NewFile(fx pkging.Pkger, osf *os.File) (*File, error) {
|
||||||
|
|
||||||
pt, err := fx.Parse(osf.Name())
|
pt, err := fx.Parse(osf.Name())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -78,7 +61,7 @@ func (f *File) Name() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *File) Open(name string) (http.File, error) {
|
func (f *File) Open(name string) (http.File, error) {
|
||||||
return &HTTPFile{f.File}, nil
|
return f.File, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *File) Path() pkging.Path {
|
func (f *File) Path() pkging.Path {
|
||||||
|
|
Loading…
Reference in New Issue