forked from mirror/pkger
improve error testing for non go directories.
also cleans up there here.Info api
This commit is contained in:
parent
2a9f9649bb
commit
812232aaff
|
@ -6,6 +6,7 @@ import (
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/markbates/pkger"
|
"github.com/markbates/pkger"
|
||||||
"github.com/markbates/pkger/internal/takeon/github.com/markbates/hepa"
|
"github.com/markbates/pkger/internal/takeon/github.com/markbates/hepa"
|
||||||
|
@ -39,7 +40,7 @@ func (e *listCmd) Exec(args []string) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
fp := info.FilePath(outName)
|
fp := filepath.Join(info.Dir, outName)
|
||||||
os.RemoveAll(fp)
|
os.RemoveAll(fp)
|
||||||
|
|
||||||
decls, err := parser.Parse(info)
|
decls, err := parser.Parse(info)
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
"path/filepath"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
@ -30,7 +31,7 @@ func (e *packCmd) Exec(args []string) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
fp := info.FilePath(outName)
|
fp := filepath.Join(info.Dir, outName)
|
||||||
os.RemoveAll(fp)
|
os.RemoveAll(fp)
|
||||||
|
|
||||||
decls, err := parser.Parse(info)
|
decls, err := parser.Parse(info)
|
||||||
|
|
94
here/dir.go
94
here/dir.go
|
@ -4,14 +4,13 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Dir attempts to gather info for the requested directory.
|
// Dir attempts to gather info for the requested directory.
|
||||||
func Dir(p string) (Info, error) {
|
func Dir(p string) (Info, error) {
|
||||||
i, err := Cache(p, func(p string) (Info, error) {
|
i, err := Cache(p, func(p string) (Info, error) {
|
||||||
|
|
||||||
var i Info
|
var i Info
|
||||||
|
|
||||||
fi, err := os.Stat(p)
|
fi, err := os.Stat(p)
|
||||||
|
@ -33,36 +32,11 @@ func Dir(p string) (Info, error) {
|
||||||
os.Chdir(p)
|
os.Chdir(p)
|
||||||
|
|
||||||
b, err := run("go", "list", "-json")
|
b, err := run("go", "list", "-json")
|
||||||
|
// go: cannot find main module; see 'go help modules'
|
||||||
|
// build .: cannot find module for path .
|
||||||
|
// no Go files in
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
return fromNonGoDir(p)
|
||||||
es := err.Error()
|
|
||||||
if strings.Contains(es, "cannot find module for path .") || strings.Contains(es, "no Go files") || strings.Contains(es, "can't load package") {
|
|
||||||
if _, err := os.Stat(fmt.Sprintf("%s/go.mod", p)); err == nil {
|
|
||||||
var mod Module
|
|
||||||
bm, err := run("go", "list", "-m", "-json")
|
|
||||||
if err != nil {
|
|
||||||
return i, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := json.Unmarshal(bm, &mod); err != nil {
|
|
||||||
return i, err
|
|
||||||
}
|
|
||||||
info := NewInfoFromPath(p, mod)
|
|
||||||
prepareInfo(p, info, &i)
|
|
||||||
|
|
||||||
return i, err
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return i, err
|
|
||||||
}
|
|
||||||
|
|
||||||
info, err := Dir(filepath.Dir(p))
|
|
||||||
if err != nil {
|
|
||||||
return info, err
|
|
||||||
}
|
|
||||||
|
|
||||||
prepareInfo(p, info, &i)
|
|
||||||
return i, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := json.Unmarshal(b, &i); err != nil {
|
if err := json.Unmarshal(b, &i); err != nil {
|
||||||
|
@ -76,20 +50,62 @@ func Dir(p string) (Info, error) {
|
||||||
return i, err
|
return i, err
|
||||||
}
|
}
|
||||||
|
|
||||||
Cache(i.ImportPath, func(p string) (Info, error) {
|
return Cache(i.ImportPath, func(p string) (Info, error) {
|
||||||
return i, nil
|
return i, nil
|
||||||
})
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func dir(p string) (Info, error) {
|
||||||
|
var i Info
|
||||||
|
|
||||||
|
fi, err := os.Stat(p)
|
||||||
|
if err != nil {
|
||||||
|
return i, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if !fi.IsDir() {
|
||||||
|
p = filepath.Dir(p)
|
||||||
|
}
|
||||||
|
|
||||||
|
pwd, err := os.Getwd()
|
||||||
|
if err != nil {
|
||||||
|
return i, err
|
||||||
|
}
|
||||||
|
|
||||||
|
defer os.Chdir(pwd)
|
||||||
|
|
||||||
|
os.Chdir(p)
|
||||||
|
|
||||||
|
b, err := run("go", "list", "-json")
|
||||||
|
// go: cannot find main module; see 'go help modules'
|
||||||
|
// build .: cannot find module for path .
|
||||||
|
// no Go files in
|
||||||
|
if err != nil {
|
||||||
|
return fromNonGoDir(p)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := json.Unmarshal(b, &i); err != nil {
|
||||||
|
return i, err
|
||||||
|
}
|
||||||
|
|
||||||
return i, nil
|
return i, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func prepareInfo(p string, info Info, target *Info) {
|
func fromNonGoDir(dir string) (Info, error) {
|
||||||
target.Module = info.Module
|
fmt.Println(">>>TODO here/dir.go:59: dir ", dir)
|
||||||
ph := strings.TrimPrefix(p, target.Module.Dir)
|
i := Info{
|
||||||
|
Dir: dir,
|
||||||
|
}
|
||||||
|
|
||||||
target.ImportPath = path.Join(info.Module.Path, ph)
|
b, err := run("go", "list", "-json", "-m")
|
||||||
target.Name = path.Base(target.ImportPath)
|
if err != nil {
|
||||||
|
return i, err
|
||||||
|
}
|
||||||
|
|
||||||
ph = filepath.Join(info.Module.Dir, ph)
|
if err := json.Unmarshal(b, &i.Module); err != nil {
|
||||||
target.Dir = ph
|
return i, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return i, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
package here_test
|
package here_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/markbates/pkger/here"
|
||||||
"github.com/markbates/pkger/pkging/pkgtest"
|
"github.com/markbates/pkger/pkging/pkgtest"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
@ -13,18 +16,43 @@ func Test_Dir(t *testing.T) {
|
||||||
ref, err := pkgtest.NewRef()
|
ref, err := pkgtest.NewRef()
|
||||||
r.NoError(err)
|
r.NoError(err)
|
||||||
|
|
||||||
|
root := ref.Dir
|
||||||
|
|
||||||
|
r.NoError(err)
|
||||||
|
defer os.RemoveAll(root)
|
||||||
|
|
||||||
|
public := filepath.Join(root, "public")
|
||||||
|
r.NoError(os.MkdirAll(public, 0755))
|
||||||
|
|
||||||
|
gf := filepath.Join(root, "cmd", "main.go")
|
||||||
|
r.NoError(os.MkdirAll(filepath.Dir(gf), 0755))
|
||||||
|
|
||||||
|
f, err := os.Create(gf)
|
||||||
|
r.NoError(err)
|
||||||
|
|
||||||
|
_, err = f.Write([]byte("package main"))
|
||||||
|
r.NoError(err)
|
||||||
|
|
||||||
|
r.NoError(f.Close())
|
||||||
|
|
||||||
table := []struct {
|
table := []struct {
|
||||||
in string
|
in string
|
||||||
err bool
|
err bool
|
||||||
}{
|
}{
|
||||||
{in: ref.Dir, err: false},
|
{in: root, err: false},
|
||||||
|
{in: public, err: false},
|
||||||
|
{in: gf, err: false},
|
||||||
|
{in: filepath.Join(root, "."), err: false},
|
||||||
|
{in: "/unknown", err: true},
|
||||||
}
|
}
|
||||||
for _, tt := range table {
|
for _, tt := range table {
|
||||||
t.Run(tt.in, func(st *testing.T) {
|
t.Run(tt.in, func(st *testing.T) {
|
||||||
r := require.New(st)
|
r := require.New(st)
|
||||||
|
|
||||||
|
_, err = here.Dir(tt.in)
|
||||||
if tt.err {
|
if tt.err {
|
||||||
r.Error(err)
|
r.Error(err)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
r.NoError(err)
|
r.NoError(err)
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
"regexp"
|
||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -37,3 +38,11 @@ func Cache(p string, fn func(string) (Info, error)) (Info, error) {
|
||||||
cache.Store(p, i)
|
cache.Store(p, i)
|
||||||
return i, nil
|
return i, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ClearCache() {
|
||||||
|
cache = &infoMap{
|
||||||
|
data: &sync.Map{},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var nonGoDirRx = regexp.MustCompile(`cannot find main|go help modules|go: |build .:|no Go files`)
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
package here
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Test_nonGoDirRx(t *testing.T) {
|
||||||
|
r := require.New(t)
|
||||||
|
r.False(nonGoDirRx.MatchString(""))
|
||||||
|
r.False(nonGoDirRx.MatchString("hello"))
|
||||||
|
|
||||||
|
table := []string{
|
||||||
|
"go: cannot find main module; see 'go help modules'",
|
||||||
|
"go help modules",
|
||||||
|
"go: ",
|
||||||
|
"build .:",
|
||||||
|
"no Go files",
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range table {
|
||||||
|
t.Run(tt, func(st *testing.T) {
|
||||||
|
r := require.New(st)
|
||||||
|
|
||||||
|
b := nonGoDirRx.MatchString(tt)
|
||||||
|
r.True(b)
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
46
here/info.go
46
here/info.go
|
@ -2,10 +2,6 @@ package here
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
"runtime"
|
|
||||||
"strings"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Info represents details about the directory/package
|
// Info represents details about the directory/package
|
||||||
|
@ -16,15 +12,6 @@ type Info struct {
|
||||||
Module Module
|
Module Module
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewInfoFromPath initialize a Info with a basic information and his module
|
|
||||||
// this method could be used when the Unmarshal information is not possible
|
|
||||||
func NewInfoFromPath(path string, m Module) Info {
|
|
||||||
return Info{
|
|
||||||
Dir: path,
|
|
||||||
Module: m,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (i Info) MarshalJSON() ([]byte, error) {
|
func (i Info) MarshalJSON() ([]byte, error) {
|
||||||
mm := map[string]interface{}{
|
mm := map[string]interface{}{
|
||||||
"ImportPath": i.ImportPath,
|
"ImportPath": i.ImportPath,
|
||||||
|
@ -36,45 +23,12 @@ func (i Info) MarshalJSON() ([]byte, error) {
|
||||||
return json.Marshal(mm)
|
return json.Marshal(mm)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i Info) FilePath(paths ...string) string {
|
|
||||||
res := []string{i.Dir}
|
|
||||||
for _, p := range paths {
|
|
||||||
p = strings.TrimPrefix(p, i.Dir)
|
|
||||||
p = strings.TrimPrefix(p, "/")
|
|
||||||
if runtime.GOOS == "windows" {
|
|
||||||
p = strings.Replace(p, "/", "\\", -1)
|
|
||||||
}
|
|
||||||
res = append(res, p)
|
|
||||||
}
|
|
||||||
return filepath.Join(res...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (i Info) Open(p string) (*os.File, error) {
|
|
||||||
return os.Open(i.FilePath(p))
|
|
||||||
}
|
|
||||||
|
|
||||||
// ModuleName returns the name of the current
|
|
||||||
// module, or if not using modules, the current
|
|
||||||
// package. These *might* not match.
|
|
||||||
func (i Info) ModuleName() string {
|
|
||||||
if i.Mods() {
|
|
||||||
return i.Module.Path
|
|
||||||
}
|
|
||||||
return i.ImportPath
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsZero checks if the type has been filled
|
// IsZero checks if the type has been filled
|
||||||
// with rich chocolately data goodness
|
// with rich chocolately data goodness
|
||||||
func (i Info) IsZero() bool {
|
func (i Info) IsZero() bool {
|
||||||
return i.String() == Info{}.String()
|
return i.String() == Info{}.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mods returns whether Go modules are used
|
|
||||||
// in this directory/package.
|
|
||||||
func (i Info) Mods() bool {
|
|
||||||
return !i.Module.IsZero()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (i Info) String() string {
|
func (i Info) String() string {
|
||||||
b, err := json.MarshalIndent(i, "", " ")
|
b, err := json.MarshalIndent(i, "", " ")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -50,21 +50,18 @@ func Test_Parser_Ref(t *testing.T) {
|
||||||
func Test_Parser_Example_HTTP(t *testing.T) {
|
func Test_Parser_Example_HTTP(t *testing.T) {
|
||||||
r := require.New(t)
|
r := require.New(t)
|
||||||
|
|
||||||
cur, err := here.Current()
|
here.ClearCache()
|
||||||
|
cur, err := here.Package("github.com/markbates/pkger")
|
||||||
r.NoError(err)
|
r.NoError(err)
|
||||||
|
|
||||||
pwd, err := os.Getwd()
|
|
||||||
r.NoError(err)
|
|
||||||
defer os.Chdir(pwd)
|
|
||||||
|
|
||||||
root := filepath.Join(cur.Dir, "examples", "http", "pkger")
|
root := filepath.Join(cur.Dir, "examples", "http", "pkger")
|
||||||
r.NoError(os.Chdir(root))
|
|
||||||
defer func() {
|
defer func() {
|
||||||
c := exec.Command("go", "mod", "tidy", "-v")
|
c := exec.Command("go", "mod", "tidy", "-v")
|
||||||
c.Run()
|
c.Run()
|
||||||
}()
|
}()
|
||||||
|
|
||||||
her, err := here.Dir(".")
|
her, err := here.Dir(root)
|
||||||
r.NoError(err)
|
r.NoError(err)
|
||||||
|
|
||||||
res, err := Parse(her)
|
res, err := Parse(her)
|
||||||
|
|
|
@ -17,6 +17,7 @@ type Ref struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewRef() (*Ref, error) {
|
func NewRef() (*Ref, error) {
|
||||||
|
here.ClearCache()
|
||||||
her, err := here.Package("github.com/markbates/pkger")
|
her, err := here.Package("github.com/markbates/pkger")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
Loading…
Reference in New Issue