mirror of https://github.com/markbates/pkger.git
camera's flash
This commit is contained in:
parent
830ed679a8
commit
fa998dbcb3
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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")
|
||||
|
||||
|
|
|
@ -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())
|
||||
|
||||
|
|
|
@ -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
|
||||
})
|
||||
|
|
36
create.go
36
create.go
|
@ -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
|
||||
}
|
|
@ -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())
|
||||
}
|
55
dir.go
55
dir.go
|
@ -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
|
||||
|
||||
}
|
|
@ -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=
|
||||
|
|
179
file.go
179
file.go
|
@ -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
|
||||
|
||||
}
|
139
file_info.go
139
file_info.go
|
@ -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
|
||||
}
|
108
file_test.go
108
file_test.go
|
@ -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))
|
||||
}
|
144
files_map.go
144
files_map.go
|
@ -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())
|
||||
}
|
|
@ -1,6 +0,0 @@
|
|||
package pkger
|
||||
|
||||
func Exclude(fl *File, excludes ...string) error {
|
||||
fl.excludes = append(fl.excludes, excludes...)
|
||||
return nil
|
||||
}
|
3
go.mod
3
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
|
||||
)
|
||||
|
|
9
go.sum
9
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=
|
||||
|
|
17
info.go
17
info.go
|
@ -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
|
||||
}
|
126
infos_map.go
126
infos_map.go
|
@ -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
|
||||
}
|
83
json.go
83
json.go
|
@ -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
|
||||
}
|
79
open.go
79
open.go
|
@ -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
|
||||
}
|
124
open_test.go
124
open_test.go
|
@ -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), `<a href="/cmd/pkger/main.go">/cmd/pkger/main.go</a>`)
|
||||
//
|
||||
// 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), `<a href="radio.radio">radio.radio</a>`)
|
||||
// }
|
||||
//
|
||||
// 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), `<a href="/radio.radio">/radio.radio</a>`)
|
||||
// r.NotContains(string(b), `/public`)
|
||||
// r.NotContains(string(b), `//`)
|
||||
// }
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
99
path.go
99
path.go
|
@ -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
|
||||
}
|
52
path_test.go
52
path_test.go
|
@ -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)
|
||||
})
|
||||
}
|
||||
}
|
123
paths_map.go
123
paths_map.go
|
@ -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
|
||||
}
|
126
pkger.go
126
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
|
||||
|
|
|
@ -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`
|
14
stat.go
14
stat.go
|
@ -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
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
package pkger
|
||||
|
||||
// Version of pkger
|
||||
const Version = "v0.0.1"
|
70
walk.go
70
walk.go
|
@ -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
|
||||
}
|
Loading…
Reference in New Issue