that's what i get

This commit is contained in:
Mark Bates 2019-08-03 16:36:56 -04:00
parent 34a3aeb632
commit a4a55a52dc
19 changed files with 214 additions and 124 deletions

View File

@ -8,7 +8,7 @@ import (
) )
func list(args []string) error { func list(args []string) error {
info, err := pkger.Current() info, err := pkger.Stat()
if err != nil { if err != nil {
return err return err
} }

View File

@ -12,7 +12,7 @@ import (
const outName = "pkged.go" const outName = "pkged.go"
func pack(args []string) error { func pack(args []string) error {
info, err := pkger.Current() info, err := pkger.Stat()
if err != nil { if err != nil {
return err return err
} }
@ -41,7 +41,7 @@ func Package(out string, paths []pkger.Path) error {
return err return err
} }
c, err := pkger.Current() c, err := pkger.Stat()
if err != nil { if err != nil {
return err return err
} }

View File

@ -8,6 +8,6 @@ func Info(p string) (here.Info, error) {
return rootIndex.Info(p) return rootIndex.Info(p)
} }
func Current() (here.Info, error) { func Stat() (here.Info, error) {
return rootIndex.Current() return rootIndex.Stat()
} }

7
debug.go Normal file
View File

@ -0,0 +1,7 @@
// +build debug
package pkger
func Debug(format string, a ...interface{}) {
fmt.Println("[PKGER] ", fmt.Sprintf(format, a...)
}

5
debug_shim.go Normal file
View File

@ -0,0 +1,5 @@
// +build !debug
package pkger
func Debug(format string, a ...interface{}) {}

10
file.go
View File

@ -8,6 +8,7 @@ import (
"io/ioutil" "io/ioutil"
"net/http" "net/http"
"os" "os"
"path"
"time" "time"
"github.com/gobuffalo/here" "github.com/gobuffalo/here"
@ -62,12 +63,8 @@ func (f *File) Close() error {
} }
func (f *File) Read(p []byte) (int, error) { func (f *File) Read(p []byte) (int, error) {
if len(f.data) > 0 && len(f.data) <= len(p) { if len(f.data) > 0 && f.reader == nil {
return copy(p, f.data), io.EOF f.reader = bytes.NewReader(f.data)
}
if len(f.data) > 0 {
f.reader = ioutil.NopCloser(bytes.NewReader(f.data))
} }
if f.reader != nil { if f.reader != nil {
@ -168,6 +165,7 @@ func (f *File) Open(name string) (http.File, error) {
return f, nil return f, nil
} }
pt.Name = path.Join(f.Path().Name, pt.Name)
return rootIndex.Open(pt) return rootIndex.Open(pt)
} }

View File

@ -13,12 +13,18 @@ import (
// value: *File // value: *File
type filesMap struct { type filesMap struct {
data *sync.Map data *sync.Map
once *sync.Once
} }
func (m *filesMap) Data() *sync.Map { func (m *filesMap) Data() *sync.Map {
if m.data == nil { if m.once == nil {
m.data = &sync.Map{} m.once = &sync.Once{}
} }
m.once.Do(func() {
if m.data == nil {
m.data = &sync.Map{}
}
})
return m.data return m.data
} }

151
index.go
View File

@ -1,7 +1,6 @@
package pkger package pkger
import ( import (
"encoding/json"
"fmt" "fmt"
"os" "os"
"path/filepath" "path/filepath"
@ -10,17 +9,40 @@ import (
"time" "time"
"github.com/gobuffalo/here" "github.com/gobuffalo/here"
"github.com/markbates/hepa"
"github.com/markbates/hepa/filters"
) )
type index struct { type index struct {
Files *filesMap Files *filesMap `json:"files"`
Infos *infosMap Infos *infosMap `json:"infos"`
current here.Info Paths *pathsMap `json:"paths"`
Current here.Info `json:"current"`
once sync.Once once sync.Once
} }
func (i *index) Parse(p string) (Path, error) {
pt, ok := i.Paths.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])
return rootIndex.Parse(p)
}
func (i *index) Info(p string) (here.Info, error) { func (i *index) Info(p string) (here.Info, error) {
info, ok := i.Infos.Load(p) info, ok := i.Infos.Load(p)
if ok { if ok {
@ -35,14 +57,14 @@ func (i *index) Info(p string) (here.Info, error) {
return info, nil return info, nil
} }
func (i *index) Current() (here.Info, error) { func (i *index) Stat() (here.Info, error) {
i.once.Do(func() { i.once.Do(func() {
i.current, _ = here.Cache("", func(string) (here.Info, error) { i.Current, _ = here.Cache("", func(string) (here.Info, error) {
return here.Current() return here.Current()
}) })
}) })
return i.current, nil return i.Current, nil
} }
func (i *index) Create(pt Path) (*File, error) { func (i *index) Create(pt Path) (*File, error) {
@ -60,63 +82,67 @@ func (i *index) Create(pt Path) (*File, error) {
}, },
} }
if i.Files == nil {
i.Files = &filesMap{}
}
i.Files.Store(pt, f) i.Files.Store(pt, f)
return f, nil return f, nil
} }
func (i *index) MarshalJSON() ([]byte, error) { // func (i *index) MarshalJSON() ([]byte, error) {
m := map[string]interface{}{} // m := map[string]interface{}{}
//
// m["files"] = i.Files
// m["infos"] = i.Infos
// m["current"] = i.Current
//
// b, err := json.Marshal(m)
// if err != nil {
// return nil, err
// }
//
// hep := hepa.New()
// hep = hepa.With(hep, filters.Golang())
// hep = hepa.With(hep, filters.Secrets())
// return hep.Filter(b)
// }
m["files"] = i.Files // func (i *index) UnmarshalJSON(b []byte) error {
m["infos"] = i.Infos // m := map[string]json.RawMessage{}
m["current"] = i.current //
// if err := json.Unmarshal(b, &m); err != nil {
b, err := json.Marshal(m) // return err
if err != nil { // }
return nil, err //
} // infos, ok := m["infos"]
// if !ok {
hep := hepa.New() // return fmt.Errorf("missing infos")
hep = hepa.With(hep, filters.Golang()) // }
hep = hepa.With(hep, filters.Secrets()) // i.Infos = &infosMap{}
return hep.Filter(b) // if err := json.Unmarshal(infos, i.Infos); err != nil {
} // return err
// }
func (i *index) UnmarshalJSON(b []byte) error { //
m := map[string]json.RawMessage{} // files, ok := m["files"]
// if !ok {
if err := json.Unmarshal(b, &m); err != nil { // return fmt.Errorf("missing files")
return err // }
} //
// i.Files = &filesMap{}
infos, ok := m["infos"] // if err := json.Unmarshal(files, i.Files); err != nil {
if !ok { // return err
return fmt.Errorf("missing infos") // }
} //
i.Infos = &infosMap{} // current, ok := m["current"]
if err := json.Unmarshal(infos, i.Infos); err != nil { // if !ok {
return err // return fmt.Errorf("missing current")
} // }
// if err := json.Unmarshal(current, &i.Current); err != nil {
files, ok := m["files"] // return err
if !ok { // }
return fmt.Errorf("missing files") // return nil
} // }
i.Files = &filesMap{}
if err := json.Unmarshal(files, i.Files); err != nil {
return err
}
current, ok := m["current"]
if !ok {
return fmt.Errorf("missing current")
}
if err := json.Unmarshal(current, &i.current); err != nil {
return err
}
return nil
}
func (i index) Walk(pt Path, wf WalkFunc) error { func (i index) Walk(pt Path, wf WalkFunc) error {
var err error var err error
@ -136,7 +162,7 @@ func (i index) Walk(pt Path, wf WalkFunc) error {
var info here.Info var info here.Info
if pt.Pkg == "." { if pt.Pkg == "." {
info, err = Current() info, err = Stat()
if err != nil { if err != nil {
return err return err
} }
@ -207,6 +233,7 @@ func newIndex() *index {
return &index{ return &index{
Files: &filesMap{}, Files: &filesMap{},
Infos: &infosMap{}, Infos: &infosMap{},
Paths: &pathsMap{},
} }
} }

View File

@ -77,7 +77,7 @@ func Test_index_JSON(t *testing.T) {
fmt.Fprint(f, radio) fmt.Fprint(f, radio)
r.NoError(f.Close()) r.NoError(f.Close())
c, err := i.Current() c, err := i.Stat()
r.NoError(err) r.NoError(err)
r.Equal(curPkg, c.ImportPath) r.Equal(curPkg, c.ImportPath)
@ -86,7 +86,7 @@ func Test_index_JSON(t *testing.T) {
r.Equal(1, len(i.Files.Keys())) r.Equal(1, len(i.Files.Keys()))
r.Equal(1, len(i.Infos.Keys())) r.Equal(1, len(i.Infos.Keys()))
r.NotZero(i.current) r.NotZero(i.Current)
jason, err := json.Marshal(i) jason, err := json.Marshal(i)
r.NoError(err) r.NoError(err)
@ -98,7 +98,7 @@ func Test_index_JSON(t *testing.T) {
r.NotNil(i2.Infos) r.NotNil(i2.Infos)
r.NotNil(i2.Files) r.NotNil(i2.Files)
r.NotZero(i2.current) r.NotZero(i2.Current)
r.Equal(1, len(i2.Files.Keys())) r.Equal(1, len(i2.Files.Keys()))
r.Equal(1, len(i2.Infos.Keys())) r.Equal(1, len(i2.Infos.Keys()))

View File

@ -16,11 +16,14 @@ import (
// value: here.Info // value: here.Info
type infosMap struct { type infosMap struct {
data *sync.Map data *sync.Map
init sync.Once once *sync.Once
} }
func (m *infosMap) Data() *sync.Map { func (m *infosMap) Data() *sync.Map {
m.init.Do(func() { if m.once == nil {
m.once = &sync.Once{}
}
m.once.Do(func() {
if m.data == nil { if m.data == nil {
m.data = &sync.Map{} m.data = &sync.Map{}
} }

2
internal/examples/app/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
example
app

View File

@ -0,0 +1,7 @@
FROM alpine
EXPOSE 3000
COPY example /bin/
RUN ls -la
CMD /bin/example

View File

@ -0,0 +1,6 @@
default:
cd ../../../cmd/pkger && go install -v .
pkger
GOOS=linux go build -v -o example
docker build -t pkger:example .
docker run -p 3000:3000 pkger:example

View File

@ -4,6 +4,8 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
github.com/gobuffalo/here v0.2.2 h1:AXEK2ApOb4F5cKZ46Ofi8inGWa0qy5ChmJXAK5/IDmo= github.com/gobuffalo/here v0.2.2 h1:AXEK2ApOb4F5cKZ46Ofi8inGWa0qy5ChmJXAK5/IDmo=
github.com/gobuffalo/here v0.2.2/go.mod h1:2a6G14FaAKOGJMK/5UNa4Og/+iyFS5cq3MnlvFR7YDk= github.com/gobuffalo/here v0.2.2/go.mod h1:2a6G14FaAKOGJMK/5UNa4Og/+iyFS5cq3MnlvFR7YDk=
github.com/markbates/errx v1.1.0/go.mod h1:PLa46Oex9KNbVDZhKel8v1OT7hD5JZ2eI7AHhA0wswc= github.com/markbates/errx v1.1.0/go.mod h1:PLa46Oex9KNbVDZhKel8v1OT7hD5JZ2eI7AHhA0wswc=
github.com/markbates/hepa v0.0.0-20190718154049-1d900199db5b h1:ns0oO2sMEoFJMmrbiWzGQO5AR3GgqfYRAos0gz8C0Cw=
github.com/markbates/hepa v0.0.0-20190718154049-1d900199db5b/go.mod h1:jHlCX3RNqF+epcY1FxjLyDGzr3l9+mNCh3YDDw6BFvY=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 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/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=

View File

@ -1,6 +1,7 @@
package main package main
import ( import (
"fmt"
"io" "io"
"log" "log"
"net/http" "net/http"
@ -15,10 +16,34 @@ func main() {
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
defer pub.Close()
fi, err := pub.Stat()
if err != nil {
log.Fatal(err)
}
fmt.Println(fi)
mux.Handle("/t", http.StripPrefix("/t", tmplHandler())) mux.Handle("/t", http.StripPrefix("/t", tmplHandler()))
mux.Handle("/logo", http.StripPrefix("/logo", logoHandler())) mux.Handle("/logo", http.StripPrefix("/logo", logoHandler()))
mux.Handle("/", http.FileServer(pub)) mux.Handle("/", http.FileServer(pub))
f, err := pkger.Open("/public/images/mark.png")
if err != nil {
log.Fatal(err)
}
defer f.Close()
// lcl, err := os.Create("me.png")
// if err != nil {
// log.Fatal(err)
// }
//
// if _, err := io.Copy(lcl, f); err != nil {
// log.Fatal(err)
// }
// lcl.Close()
log.Fatal(http.ListenAndServe(":3000", mux)) log.Fatal(http.ListenAndServe(":3000", mux))
} }

View File

@ -1,39 +1,14 @@
package pkger package pkger
import ( import (
"fmt"
"regexp" "regexp"
"strings" "strings"
"sync"
) )
var cache = pathsMap{
data: &sync.Map{},
}
var pathrx = regexp.MustCompile("([^:]+)(:(/.+))?") var pathrx = regexp.MustCompile("([^:]+)(:(/.+))?")
func Parse(p string) (Path, error) { func Parse(p string) (Path, error) {
pt, ok := cache.Load(p) return rootIndex.Parse(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 build(p, pkg, name string) (Path, error) { func build(p, pkg, name string) (Path, error) {
@ -42,7 +17,7 @@ func build(p, pkg, name string) (Path, error) {
Name: name, Name: name,
} }
info, err := Current() info, err := Stat()
if err != nil { if err != nil {
return pt, err return pt, err
} }
@ -59,6 +34,6 @@ func build(p, pkg, name string) (Path, error) {
if !strings.HasPrefix(pt.Name, "/") { if !strings.HasPrefix(pt.Name, "/") {
pt.Name = "/" + pt.Name pt.Name = "/" + pt.Name
} }
cache.Store(p, pt) rootIndex.Paths.Store(p, pt)
return pt, nil return pt, nil
} }

View File

@ -13,7 +13,7 @@ var DefaultIgnoredFolders = []string{".", "_", "vendor", "node_modules", "_fixtu
func Parse(name string) (Results, error) { func Parse(name string) (Results, error) {
var r Results var r Results
c, err := pkger.Current() c, err := pkger.Stat()
if err != nil { if err != nil {
return r, err return r, err
} }
@ -149,7 +149,7 @@ func sourceFiles(pt pkger.Path) ([]pkger.Path, error) {
return res, nil return res, nil
} }
c, err := pkger.Current() c, err := pkger.Stat()
if err != nil { if err != nil {
return res, err return res, err
} }

View File

@ -3,6 +3,8 @@
package pkger package pkger
import ( import (
"encoding/json"
"fmt"
"sort" "sort"
"sync" "sync"
) )
@ -12,11 +14,45 @@ import (
// value: Path // value: Path
type pathsMap struct { type pathsMap struct {
data *sync.Map 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 // Delete the key from the map
func (m *pathsMap) Delete(key string) { func (m *pathsMap) Delete(key string) {
m.data.Delete(key) m.Data().Delete(key)
} }
// Load the key from the map. // Load the key from the map.
@ -24,7 +60,7 @@ func (m *pathsMap) Delete(key string) {
// A false return indicates either the key was not found // A false return indicates either the key was not found
// or the value is not of type Path // or the value is not of type Path
func (m *pathsMap) Load(key string) (Path, bool) { func (m *pathsMap) Load(key string) (Path, bool) {
i, ok := m.data.Load(key) i, ok := m.Data().Load(key)
if !ok { if !ok {
return Path{}, false return Path{}, false
} }
@ -35,7 +71,7 @@ func (m *pathsMap) Load(key string) (Path, bool) {
// LoadOrStore will return an existing key or // LoadOrStore will return an existing key or
// store the value if not already in the map // store the value if not already in the map
func (m *pathsMap) LoadOrStore(key string, value Path) (Path, bool) { func (m *pathsMap) LoadOrStore(key string, value Path) (Path, bool) {
i, _ := m.data.LoadOrStore(key, value) i, _ := m.Data().LoadOrStore(key, value)
s, ok := i.(Path) s, ok := i.(Path)
return s, ok return s, ok
} }
@ -57,7 +93,7 @@ func (m *pathsMap) LoadOr(key string, fn func(*pathsMap) (Path, bool)) (Path, bo
// Range over the Path values in the map // Range over the Path values in the map
func (m *pathsMap) Range(f func(key string, value Path) bool) { func (m *pathsMap) Range(f func(key string, value Path) bool) {
m.data.Range(func(k, v interface{}) bool { m.Data().Range(func(k, v interface{}) bool {
key, ok := k.(string) key, ok := k.(string)
if !ok { if !ok {
return false return false
@ -72,7 +108,7 @@ func (m *pathsMap) Range(f func(key string, value Path) bool) {
// Store a Path in the map // Store a Path in the map
func (m *pathsMap) Store(key string, value Path) { func (m *pathsMap) Store(key string, value Path) {
m.data.Store(key, value) m.Data().Store(key, value)
} }
// Keys returns a list of keys in the map // Keys returns a list of keys in the map

View File

@ -47,8 +47,6 @@ func Unpack(ind string) error {
return err return err
} }
fmt.Println(rootIndex.Files.Keys())
return nil return nil
} }
@ -62,13 +60,6 @@ func Pack(out io.Writer, paths []Path) error {
if err != nil { if err != nil {
return err return err
} }
fi, err := f.Stat()
if err != nil {
return err
}
if fi.IsDir() {
continue
}
rootIndex.Files.Store(p, f) rootIndex.Files.Store(p, f)
f.Close() f.Close()
} }