one and a half stars

This commit is contained in:
Mark Bates 2019-10-21 16:23:18 -04:00
parent 2978645721
commit 2e2f6364dc
13 changed files with 1937 additions and 144 deletions

View File

@ -16,7 +16,7 @@ build: tidy
$(GO_BIN) build -v . $(GO_BIN) build -v .
make tidy make tidy
test: tidy test: tidy peg
$(GO_BIN) test -cover -tags ${TAGS} -timeout 5s ./... $(GO_BIN) test -cover -tags ${TAGS} -timeout 5s ./...
make tidy make tidy
@ -51,4 +51,6 @@ release:
release -y -f version.go --skip-packr release -y -f version.go --skip-packr
make tidy make tidy
peg:
pigeon here/internal/pathparser/parser.peg | goimports > here/internal/pathparser/parser.go
go test ./here/internal/pathparser

View File

@ -2,10 +2,8 @@ package here
import ( import (
"encoding/json" "encoding/json"
"fmt"
"os" "os"
"path/filepath" "path/filepath"
"regexp"
"runtime" "runtime"
"strings" "strings"
@ -96,58 +94,3 @@ func (i Info) String() string {
s := string(b) s := string(b)
return s return s
} }
func (i Info) Parse(p string) (Path, error) {
p = strings.TrimSpace(p)
p = filepath.Clean(p)
p = strings.TrimPrefix(p, i.Dir)
p = strings.Replace(p, "\\", "/", -1)
p = strings.TrimSpace(p)
if len(p) == 0 || p == ":" {
return i.build("", "", "")
}
res := pathrx.FindAllStringSubmatch(p, -1)
if len(res) == 0 {
return Path{}, fmt.Errorf("could not parse %q", p)
}
matches := res[0]
if len(matches) != 4 {
return Path{}, fmt.Errorf("could not parse %q", p)
}
return i.build(p, matches[1], matches[3])
}
func (i Info) build(p, pkg, name string) (Path, error) {
pt := Path{
Pkg: pkg,
Name: name,
}
if strings.HasPrefix(pt.Pkg, "/") || len(pt.Pkg) == 0 {
pt.Name = pt.Pkg
pt.Pkg = i.ImportPath
}
if len(pt.Name) == 0 {
pt.Name = "/"
}
if pt.Pkg == pt.Name {
pt.Pkg = i.ImportPath
pt.Name = "/"
}
if !strings.HasPrefix(pt.Name, "/") {
pt.Name = "/" + pt.Name
}
pt.Name = strings.TrimPrefix(pt.Name, i.Dir)
return pt, nil
}
var pathrx = regexp.MustCompile("([^:]+)(:(/.+))?")

View File

@ -0,0 +1,65 @@
package pathparser
import (
"fmt"
"strings"
)
func toString(i interface{}) (string, error) {
if i == nil {
return "", nil
}
if s, ok := i.(string); ok {
return s, nil
}
return "", fmt.Errorf("%T is not a string", i)
}
func toName(i interface{}) (string, error) {
s, err := toString(i)
if err != nil {
return "", err
}
if !strings.HasPrefix(s, "/") {
s = "/" + s
}
return s, nil
}
func toPath(pkg, name interface{}) (*Path, error) {
n, err := toString(name)
if err != nil {
return nil, err
}
pg, _ := pkg.(*Package)
p := &Path{
Name: n,
Pkg: pg,
}
// if p.IsZero() {
// return nil, fmt.Errorf("empty path")
// }
if p.Name == "" {
p.Name = "/"
}
return p, nil
}
func toPackage(n, v interface{}) (*Package, error) {
name, err := toString(n)
if err != nil {
return nil, err
}
var version string
if s, ok := v.(string); ok {
version = s
}
return &Package{
Name: name,
Version: version,
}, nil
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,37 @@
{
package pathparser
}
DOC <- pkg:PKG? n:NAME? (nl / EOF) {
return toPath(pkg, n)
}
PKG <- !"/" n:STRING v:(VERSION)? ":"? {
return toPackage(n, v)
}
NAME <- "/" n:STRING {
return toName(n)
}
VERSION <- "@" ( "v" NUMBER "." NUMBER "." NUMBER ) {
return strings.TrimPrefix( string(c.text), "@" ), nil
}
STRING <- ([^@:\\\n]+) {
return strings.TrimSpace(string(c.text)), nil
}
NUMBER <- [0-9]+ {
return strconv.Atoi(strings.TrimSpace( string(c.text) ))
}
_ "whitespace" ← [ \t]*
nl "newline" ← [\n\r]*
EOF <- !. {
return nil, nil
}

View File

@ -0,0 +1,89 @@
package pathparser
import (
"testing"
"github.com/stretchr/testify/require"
)
func Test_Parser(t *testing.T) {
table := []struct {
in string
exp Path
err bool
}{
{
in: "/a/b/c.txt",
exp: Path{
Name: "/a/b/c.txt",
},
},
{
in: "github.com/markbates/pkger:/a/b/c.txt",
exp: Path{
Pkg: &Package{
Name: "github.com/markbates/pkger",
},
Name: "/a/b/c.txt"},
},
{
in: "github.com/markbates/pkger@v1.0.0:/a/b/c.txt",
exp: Path{
Pkg: &Package{
Name: "github.com/markbates/pkger",
Version: "v1.0.0",
},
Name: "/a/b/c.txt"},
},
{
in: "github.com/markbates/pkger@v1.0.0",
exp: Path{
Pkg: &Package{
Name: "github.com/markbates/pkger",
Version: "v1.0.0",
},
Name: "/",
},
},
{
in: "github.com/markbates/pkger",
exp: Path{
Pkg: &Package{
Name: "github.com/markbates/pkger",
},
Name: "/",
},
},
{
in: "app",
exp: Path{
Pkg: &Package{
Name: "app",
},
Name: "/",
},
},
}
for _, tt := range table {
t.Run(tt.in, func(st *testing.T) {
r := require.New(st)
res, err := Parse(tt.in, []byte(tt.in))
if tt.err {
r.Error(err)
return
}
r.NoError(err)
pt, ok := res.(*Path)
r.True(ok)
r.Equal(&tt.exp, pt)
})
}
}

View File

@ -0,0 +1,15 @@
package pathparser
type Path struct {
Pkg *Package
Name string
}
func (p Path) IsZero() bool {
return p.Pkg == nil && len(p.Name) == 0
}
type Package struct {
Name string
Version string
}

44
here/parse.go Normal file
View File

@ -0,0 +1,44 @@
package here
import (
"fmt"
"strings"
"github.com/markbates/pkger/here/internal/pathparser"
)
func (i Info) Parse(p string) (Path, error) {
pt := Path{
Pkg: i.ImportPath,
Name: "/",
}
res, err := pathparser.Parse(p, []byte(p))
if err != nil {
return pt, err
}
pp, ok := res.(*pathparser.Path)
if !ok {
return pt, fmt.Errorf("expected Path, got %T", res)
}
if pp.Pkg != nil {
pt.Pkg = pp.Pkg.Name
}
pt.Name = pp.Name
her := i
if pt.Pkg != i.ImportPath {
her, err = Package(pt.Pkg)
if err != nil {
return pt, err
}
}
pt.Name = strings.TrimPrefix(pt.Name, her.Dir)
pt.Name = strings.ReplaceAll(pt.Name, "\\", "/")
return pt, nil
}

View File

@ -1,27 +1,34 @@
package pkger package pkger_test
import ( import (
"fmt"
"os" "os"
"path/filepath" "path/filepath"
"testing" "testing"
"github.com/markbates/pkger"
"github.com/markbates/pkger/here" "github.com/markbates/pkger/here"
"github.com/markbates/pkger/pkging/pkgtest"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
func Test_Parse(t *testing.T) { func Test_Parse(t *testing.T) {
r := require.New(t) r := require.New(t)
pt, err := Parse("github.com/rocket/ship:/little") app, err := pkgtest.App()
r.NoError(err) r.NoError(err)
r.Equal("github.com/rocket/ship", pt.Pkg)
r.Equal("/little", pt.Name) pt, err := pkger.Parse(fmt.Sprintf("%s:/public/index.html", app.Info.ImportPath))
r.NoError(err)
r.Equal(app.Info.ImportPath, pt.Pkg)
r.Equal("/public/index.html", pt.Name)
} }
func Test_Abs(t *testing.T) { func Test_Abs(t *testing.T) {
r := require.New(t) r := require.New(t)
s, err := Abs(":/rocket.ship") s, err := pkger.Abs("/rocket.ship")
r.NoError(err) r.NoError(err)
pwd, err := os.Getwd() pwd, err := os.Getwd()
@ -32,7 +39,7 @@ func Test_Abs(t *testing.T) {
func Test_AbsPath(t *testing.T) { func Test_AbsPath(t *testing.T) {
r := require.New(t) r := require.New(t)
s, err := AbsPath(here.Path{ s, err := pkger.AbsPath(here.Path{
Pkg: "github.com/markbates/pkger", Pkg: "github.com/markbates/pkger",
Name: "/rocket.ship", Name: "/rocket.ship",
}) })
@ -46,7 +53,7 @@ func Test_AbsPath(t *testing.T) {
func Test_Current(t *testing.T) { func Test_Current(t *testing.T) {
r := require.New(t) r := require.New(t)
info, err := Current() info, err := pkger.Current()
r.NoError(err) r.NoError(err)
r.Equal("github.com/markbates/pkger", info.ImportPath) r.Equal("github.com/markbates/pkger", info.ImportPath)
} }
@ -54,7 +61,7 @@ func Test_Current(t *testing.T) {
func Test_Info(t *testing.T) { func Test_Info(t *testing.T) {
r := require.New(t) r := require.New(t)
info, err := Info("github.com/markbates/pkger") info, err := pkger.Info("github.com/markbates/pkger")
r.NoError(err) r.NoError(err)
r.Equal("github.com/markbates/pkger", info.ImportPath) r.Equal("github.com/markbates/pkger", info.ImportPath)
} }
@ -62,9 +69,9 @@ func Test_Info(t *testing.T) {
func Test_Create(t *testing.T) { func Test_Create(t *testing.T) {
r := require.New(t) r := require.New(t)
MkdirAll("/tmp", 0755) pkger.MkdirAll("/tmp", 0755)
defer RemoveAll("/tmp") defer pkger.RemoveAll("/tmp")
f, err := Create("/tmp/test.create") f, err := pkger.Create("/tmp/test.create")
r.NoError(err) r.NoError(err)
r.Equal("/tmp/test.create", f.Name()) r.Equal("/tmp/test.create", f.Name())
r.NoError(f.Close()) r.NoError(f.Close())
@ -73,12 +80,12 @@ func Test_Create(t *testing.T) {
func Test_MkdirAll(t *testing.T) { func Test_MkdirAll(t *testing.T) {
r := require.New(t) r := require.New(t)
_, err := Open("/tmp") _, err := pkger.Open("/tmp")
r.Error(err) r.Error(err)
r.NoError(MkdirAll("/tmp", 0755)) r.NoError(pkger.MkdirAll("/tmp", 0755))
defer RemoveAll("/tmp") defer pkger.RemoveAll("/tmp")
f, err := Open("/tmp") f, err := pkger.Open("/tmp")
r.NoError(err) r.NoError(err)
r.Equal("/tmp", f.Name()) r.Equal("/tmp", f.Name())
r.NoError(f.Close()) r.NoError(f.Close())
@ -87,7 +94,7 @@ func Test_MkdirAll(t *testing.T) {
func Test_Stat(t *testing.T) { func Test_Stat(t *testing.T) {
r := require.New(t) r := require.New(t)
info, err := Stat("/go.mod") info, err := pkger.Stat("/go.mod")
r.NoError(err) r.NoError(err)
r.Equal("/go.mod", info.Name()) r.Equal("/go.mod", info.Name())
} }
@ -96,7 +103,7 @@ func Test_Walk(t *testing.T) {
r := require.New(t) r := require.New(t)
files := map[string]os.FileInfo{} files := map[string]os.FileInfo{}
err := Walk("/pkging/pkgtest/internal/testdata/app", func(path string, info os.FileInfo, err error) error { err := pkger.Walk("/pkging/pkgtest/internal/testdata/app", func(path string, info os.FileInfo, err error) error {
if err != nil { if err != nil {
return err return err
} }
@ -111,14 +118,14 @@ func Test_Walk(t *testing.T) {
func Test_Remove(t *testing.T) { func Test_Remove(t *testing.T) {
r := require.New(t) r := require.New(t)
MkdirAll("/tmp", 0755) pkger.MkdirAll("/tmp", 0755)
defer RemoveAll("/tmp") defer pkger.RemoveAll("/tmp")
f, err := Create("/tmp/test.create") f, err := pkger.Create("/tmp/test.create")
r.NoError(err) r.NoError(err)
r.Equal("/tmp/test.create", f.Name()) r.Equal("/tmp/test.create", f.Name())
r.NoError(f.Close()) r.NoError(f.Close())
r.NoError(Remove("/tmp/test.create")) r.NoError(pkger.Remove("/tmp/test.create"))
_, err = Stat("/tmp/test.create") _, err = pkger.Stat("/tmp/test.create")
r.Error(err) r.Error(err)
} }

View File

@ -15,15 +15,16 @@ func (s Suite) Test_File_Info(t *testing.T) {
pkg, err := s.Make() pkg, err := s.Make()
r.NoError(err) r.NoError(err)
cur, err := pkg.Current() app, err := App()
r.NoError(err) r.NoError(err)
ip := cur.ImportPath ip := app.Info.ImportPath
mould := "/public/index.html"
table := []struct { table := []struct {
in string in string
}{ }{
{in: mould}, {in: mould},
{in: ":" + mould},
{in: ip + ":" + mould}, {in: ip + ":" + mould},
} }
@ -39,7 +40,7 @@ func (s Suite) Test_File_Info(t *testing.T) {
f, err := pkg.Open(tt.in) f, err := pkg.Open(tt.in)
r.NoError(err) r.NoError(err)
r.Equal(mould, f.Name()) r.Equal(mould, f.Name())
r.Equal(cur.ImportPath, f.Info().ImportPath) r.Equal(ip, f.Info().ImportPath)
r.NoError(f.Close()) r.NoError(f.Close())
}) })
} }
@ -62,7 +63,7 @@ func (s Suite) Test_File_Readdir(t *testing.T) {
table := []struct { table := []struct {
in string in string
}{ }{
{in: ":/public"}, {in: "/public"},
{in: ip + ":/public"}, {in: ip + ":/public"},
} }

View File

@ -113,7 +113,6 @@ func (s Suite) Test_HTTP(t *testing.T) {
in string in string
}{ }{
{in: "/public"}, {in: "/public"},
{in: ":" + "/public"},
{in: ip + ":" + "/public"}, {in: ip + ":" + "/public"},
} }

View File

@ -17,10 +17,6 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
const mould = "/easy/listening/sugar.file"
const hart = "/easy/listening/grant.hart"
const husker = "github.com/husker/du"
type Suite struct { type Suite struct {
Name string Name string
gen func() (pkging.Pkger, error) gen func() (pkging.Pkger, error)
@ -58,6 +54,7 @@ func (s Suite) Test(t *testing.T) {
} }
func (s Suite) Run(t *testing.T, name string, fn func(t *testing.T)) { func (s Suite) Run(t *testing.T, name string, fn func(t *testing.T)) {
t.Helper()
t.Run(name, func(st *testing.T) { t.Run(name, func(st *testing.T) {
fn(st) fn(st)
}) })
@ -79,16 +76,14 @@ func (s Suite) Test_Create(t *testing.T) {
pkg, err := s.Make() pkg, err := s.Make()
r.NoError(err) r.NoError(err)
cur, err := pkg.Current() app, err := App()
r.NoError(err) r.NoError(err)
ip := cur.ImportPath
table := []struct { table := []struct {
in string in string
}{ }{
{in: mould}, {in: "/public/index.html"},
{in: ":" + mould}, {in: app.Info.ImportPath + ":" + "/public/index.html"},
{in: ip + ":" + mould},
} }
for _, tt := range table { for _, tt := range table {
@ -118,21 +113,18 @@ func (s Suite) Test_Create(t *testing.T) {
func (s Suite) Test_Create_No_MkdirAll(t *testing.T) { func (s Suite) Test_Create_No_MkdirAll(t *testing.T) {
r := require.New(t) r := require.New(t)
pkg, err := s.Make() app, err := App()
r.NoError(err) r.NoError(err)
cur, err := pkg.Current() ip := app.Info.ImportPath
r.NoError(err) mould := "/easy/listening/file.under"
ip := cur.ImportPath
table := []struct { table := []struct {
in string in string
}{ }{
{in: mould}, {in: mould},
{in: ":" + mould},
{in: ip + ":" + mould}, {in: ip + ":" + mould},
{in: filepath.Dir(mould)}, {in: filepath.Dir(mould)},
{in: ":" + filepath.Dir(mould)},
{in: ip + ":" + filepath.Dir(mould)}, {in: ip + ":" + filepath.Dir(mould)},
} }
@ -181,21 +173,18 @@ func (s Suite) Test_Info(t *testing.T) {
func (s Suite) Test_MkdirAll(t *testing.T) { func (s Suite) Test_MkdirAll(t *testing.T) {
r := require.New(t) r := require.New(t)
pkg, err := s.Make() app, err := App()
r.NoError(err) r.NoError(err)
cur, err := pkg.Current() ip := app.Info.ImportPath
r.NoError(err) mould := "/public/index.html"
ip := cur.ImportPath
table := []struct { table := []struct {
in string in string
}{ }{
{in: mould}, {in: mould},
{in: ":" + mould},
{in: ip + ":" + mould}, {in: ip + ":" + mould},
{in: filepath.Dir(mould)}, {in: filepath.Dir(mould)},
{in: ":" + filepath.Dir(mould)},
{in: ip + ":" + filepath.Dir(mould)}, {in: ip + ":" + filepath.Dir(mould)},
} }
@ -228,20 +217,17 @@ func (s Suite) Test_MkdirAll(t *testing.T) {
func (s Suite) Test_Open_File(t *testing.T) { func (s Suite) Test_Open_File(t *testing.T) {
r := require.New(t) r := require.New(t)
pkg, err := s.Make() app, err := App()
r.NoError(err) r.NoError(err)
cur, err := pkg.Current() ip := app.Info.ImportPath
r.NoError(err) mould := "/public/index.html"
ip := cur.ImportPath
table := []struct { table := []struct {
in string in string
}{ }{
{in: mould}, {in: mould},
{in: ":" + mould},
{in: ip + ":" + mould}, {in: ip + ":" + mould},
{in: hart},
} }
for _, tt := range table { for _, tt := range table {
@ -285,22 +271,17 @@ func (s Suite) Test_Parse(t *testing.T) {
r.NoError(err) r.NoError(err)
cur, err := pkg.Current() cur, err := pkg.Current()
r.NoError(err)
ip := cur.ImportPath ip := cur.ImportPath
mould := "/public/index.html"
table := []struct { table := []struct {
in string in string
exp here.Path exp here.Path
}{ }{
{in: mould, exp: here.Path{Pkg: ip, Name: mould}}, {in: mould, exp: here.Path{Pkg: ip, Name: mould}},
{in: filepath.Join(cur.Dir, mould), exp: here.Path{Pkg: ip, Name: mould}}, {in: filepath.Join(cur.Dir, mould), exp: here.Path{Pkg: ip, Name: mould}},
{in: ":" + mould, exp: here.Path{Pkg: ip, Name: mould}},
{in: ip + ":" + mould, exp: here.Path{Pkg: ip, Name: mould}}, {in: ip + ":" + mould, exp: here.Path{Pkg: ip, Name: mould}},
{in: ip, exp: here.Path{Pkg: ip, Name: "/"}}, {in: ip, exp: here.Path{Pkg: ip, Name: "/"}},
{in: ":", exp: here.Path{Pkg: ip, Name: "/"}},
{in: husker + ":" + mould, exp: here.Path{Pkg: husker, Name: mould}},
{in: husker, exp: here.Path{Pkg: husker, Name: "/"}},
{in: husker + ":", exp: here.Path{Pkg: husker, Name: "/"}},
} }
for _, tt := range table { for _, tt := range table {
@ -320,19 +301,18 @@ func (s Suite) Test_Stat_Error(t *testing.T) {
pkg, err := s.Make() pkg, err := s.Make()
r.NoError(err) r.NoError(err)
cur, err := pkg.Current() app, err := App()
r.NoError(err) r.NoError(err)
ip := cur.ImportPath ip := app.Info.ImportPath
table := []struct { table := []struct {
in string in string
}{ }{
{in: hart}, {in: "/dontexist"},
{in: ":" + hart},
{in: ip}, {in: ip},
{in: ip + ":"}, {in: ip + ":"},
{in: ip + ":" + hart}, {in: ip + ":" + "/dontexist"},
} }
for _, tt := range table { for _, tt := range table {
@ -357,18 +337,17 @@ func (s Suite) Test_Stat_Dir(t *testing.T) {
pkg, err := s.Make() pkg, err := s.Make()
r.NoError(err) r.NoError(err)
cur, err := pkg.Current() app, err := App()
r.NoError(err) r.NoError(err)
dir := filepath.Dir(mould) ip := app.Info.ImportPath
ip := cur.ImportPath dir := app.Paths.Public[1]
table := []struct { table := []struct {
in string in string
}{ }{
{in: ip}, {in: ip},
{in: dir}, {in: dir},
{in: ":" + dir},
{in: ip + ":" + dir}, {in: ip + ":" + dir},
} }
@ -393,20 +372,17 @@ func (s Suite) Test_Stat_Dir(t *testing.T) {
func (s Suite) Test_Stat_File(t *testing.T) { func (s Suite) Test_Stat_File(t *testing.T) {
r := require.New(t) r := require.New(t)
pkg, err := s.Make() app, err := App()
r.NoError(err) r.NoError(err)
cur, err := pkg.Current() ip := app.Info.ImportPath
r.NoError(err) mould := "/public/index.html"
ip := cur.ImportPath
table := []struct { table := []struct {
in string in string
}{ }{
{in: mould}, {in: mould},
{in: ":" + mould},
{in: ip + ":" + mould}, {in: ip + ":" + mould},
{in: hart},
} }
for _, tt := range table { for _, tt := range table {
@ -517,7 +493,6 @@ func (s Suite) Test_Remove(t *testing.T) {
in string in string
}{ }{
{in: "/public/images/img1.png"}, {in: "/public/images/img1.png"},
{in: ":/public/images/img1.png"},
{in: ip + ":/public/images/img1.png"}, {in: ip + ":/public/images/img1.png"},
} }
@ -558,7 +533,6 @@ func (s Suite) Test_RemoveAll(t *testing.T) {
in string in string
}{ }{
{in: "/public"}, {in: "/public"},
{in: ":/public"},
{in: ip + ":/public"}, {in: ip + ":/public"},
} }

View File

@ -13,20 +13,17 @@ import (
func (s Suite) Test_Util_ReadFile(t *testing.T) { func (s Suite) Test_Util_ReadFile(t *testing.T) {
r := require.New(t) r := require.New(t)
pkg, err := s.Make() app, err := App()
r.NoError(err) r.NoError(err)
cur, err := pkg.Current() ip := app.Info.ImportPath
r.NoError(err) mould := "/public/index.html"
ip := cur.ImportPath
table := []struct { table := []struct {
in string in string
}{ }{
{in: mould}, {in: mould},
{in: ":" + mould},
{in: ip + ":" + mould}, {in: ip + ":" + mould},
{in: hart},
} }
for _, tt := range table { for _, tt := range table {