diff --git a/examples/http/pkger/go.mod b/examples/http/pkger/go.mod index 8550ba4..7ca89e0 100644 --- a/examples/http/pkger/go.mod +++ b/examples/http/pkger/go.mod @@ -2,4 +2,6 @@ module app go 1.13 -require github.com/markbates/pkger v0.0.0-20191016200917-09e9684b656b +require github.com/markbates/pkger v0.5.0 + +replace github.com/markbates/pkger => ../../../ diff --git a/examples/http/pkger/go.sum b/examples/http/pkger/go.sum index 66386d4..3bc4a9a 100644 --- a/examples/http/pkger/go.sum +++ b/examples/http/pkger/go.sum @@ -6,8 +6,6 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN 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/pkger v0.0.0-20191016200917-09e9684b656b h1:cXYQ3JZQkRLFyN8m22Q58mOhdKyTooPqvGt8pyWR8eA= -github.com/markbates/pkger v0.0.0-20191016200917-09e9684b656b/go.mod h1:0nBNvgA9jJk9gWhO/BcIYz1qJ8BJ0MWCSyKFPApdWNs= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -18,3 +16,5 @@ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33 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= +gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/examples/http/pkger/main.go b/examples/http/pkger/main.go index ba48d30..dcb75e2 100644 --- a/examples/http/pkger/main.go +++ b/examples/http/pkger/main.go @@ -14,10 +14,9 @@ func main() { } func run() error { - f, err := pkger.Open("/public") + dir, err := pkger.HTTP("/public") if err != nil { return err } - dir := http.FileServer(f) return http.ListenAndServe(":3000", dir) } diff --git a/examples/walk/std/go.mod b/examples/walk/std/go.mod index 3294603..cd874ab 100644 --- a/examples/walk/std/go.mod +++ b/examples/walk/std/go.mod @@ -1,3 +1,5 @@ module app go 1.13 + +require github.com/markbates/pkger v0.4.0 // indirect diff --git a/examples/walk/std/go.sum b/examples/walk/std/go.sum new file mode 100644 index 0000000..99c3bc3 --- /dev/null +++ b/examples/walk/std/go.sum @@ -0,0 +1,18 @@ +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/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/markbates/pkger v0.4.0 h1:fIzmOXYsJV+nFS+RtsmWZvXeH5DDGQtF/SwKJgfgVoE= +github.com/markbates/pkger v0.4.0/go.mod h1:so/QD8FeTM0IilC3nRArkwOvUT+tsJsaXLFUAKmjzJk= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/parser/http.go b/parser/http.go new file mode 100644 index 0000000..aecdc02 --- /dev/null +++ b/parser/http.go @@ -0,0 +1,87 @@ +package parser + +import ( + "encoding/json" + "go/token" + "os" + "path/filepath" + + "github.com/markbates/pkger" + "github.com/markbates/pkger/here" +) + +var _ Decl = HTTPDecl{} + +type HTTPDecl struct { + file *File + pos token.Pos + value string +} + +func (d HTTPDecl) MarshalJSON() ([]byte, error) { + return json.Marshal(map[string]interface{}{ + "type": "pkger.HTTP", + "file": d.file, + "pos": d.pos, + "value": d.value, + }) +} + +func (d HTTPDecl) File() (*File, error) { + if d.file == nil { + return nil, os.ErrNotExist + } + return d.file, nil +} + +func (d HTTPDecl) Pos() (token.Pos, error) { + if d.pos <= 0 { + return -1, os.ErrNotExist + } + return d.pos, nil +} + +func (d HTTPDecl) Value() (string, error) { + if d.value == "" { + return "", os.ErrNotExist + } + return d.value, nil +} + +func (d HTTPDecl) Files() ([]*File, error) { + + pt, err := pkger.Parse(d.value) + if err != nil { + return nil, err + } + + her, err := here.Package(pt.Pkg) + if err != nil { + return nil, err + } + + fp := filepath.Join(her.Dir, pt.Name) + + osf, err := os.Stat(fp) + if err != nil { + return nil, err + } + + if osf.IsDir() { + wd := WalkDecl{ + file: d.file, + pos: d.pos, + value: d.value, + } + return wd.Files() + } + + var files []*File + files = append(files, &File{ + Abs: filepath.Join(her.Dir, pt.Name), + Path: pt, + Here: her, + }) + + return files, nil +} diff --git a/parser/visitor.go b/parser/visitor.go index d6ea0f4..5483ed7 100644 --- a/parser/visitor.go +++ b/parser/visitor.go @@ -32,6 +32,10 @@ func (f *file) find() (Decls, error) { return nil, err } + if err := f.findHTTPCalls(); err != nil { + return nil, err + } + if err := f.findWalkCalls(); err != nil { return nil, err } @@ -136,6 +140,48 @@ func (f *file) findWalkCalls() error { return err } +func (f *file) findHTTPCalls() error { + var err error + f.walk(func(node ast.Node) bool { + ce, ok := node.(*ast.CallExpr) + if !ok { + return true + } + + exists := isPkgDot(ce.Fun, "pkger", "HTTP") + if !(exists) || len(ce.Args) != 1 { + return true + } + + n := ce.Args[0] + + s, err := f.asValue(n) + if err != nil { + return false + } + + info, err := here.Dir(filepath.Dir(f.filename)) + if err != nil { + return false + } + + pf := &File{ + Abs: f.filename, + Here: info, + } + + decl := HTTPDecl{ + file: pf, + pos: n.Pos(), + value: s, + } + + f.decls = append(f.decls, decl) + return true + }) + return err +} + // helpers // ======= func isPkgDot(expr ast.Expr, pkg, name string) bool { diff --git a/pkger.go b/pkger.go index aae7067..62cf39c 100644 --- a/pkger.go +++ b/pkger.go @@ -2,6 +2,7 @@ package pkger import ( "log" + "net/http" "os" "path/filepath" "sync" @@ -94,3 +95,12 @@ func Remove(name string) error { func RemoveAll(name string) error { return impl().RemoveAll(name) } + +// HTTP returns an http.FileServer for the specified path. +func HTTP(p string) (http.Handler, error) { + f, err := Open(p) + if err != nil { + return nil, err + } + return http.FileServer(f), nil +}