mirror of https://github.com/markbates/pkger.git
Adds -include flag and pkger.Include directive fixes #28
This commit is contained in:
parent
1a3cb0f04d
commit
7ee0500044
2
Makefile
2
Makefile
|
@ -17,7 +17,7 @@ build: tidy
|
||||||
make tidy
|
make tidy
|
||||||
|
|
||||||
test: tidy
|
test: tidy
|
||||||
$(GO_BIN) test -count 1 -cover -tags ${TAGS} -timeout 10s ./...
|
$(GO_BIN) test -count 1 -cover -tags ${TAGS} -timeout 1m ./...
|
||||||
make tidy
|
make tidy
|
||||||
|
|
||||||
cov:
|
cov:
|
||||||
|
|
|
@ -16,9 +16,10 @@ import (
|
||||||
|
|
||||||
type listCmd struct {
|
type listCmd struct {
|
||||||
*flag.FlagSet
|
*flag.FlagSet
|
||||||
help bool
|
help bool
|
||||||
json bool
|
json bool
|
||||||
subs []command
|
include slice
|
||||||
|
subs []command
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *listCmd) Name() string {
|
func (e *listCmd) Name() string {
|
||||||
|
@ -43,7 +44,7 @@ func (e *listCmd) Exec(args []string) error {
|
||||||
fp := filepath.Join(info.Dir, outName)
|
fp := filepath.Join(info.Dir, outName)
|
||||||
os.RemoveAll(fp)
|
os.RemoveAll(fp)
|
||||||
|
|
||||||
decls, err := parser.Parse(info)
|
decls, err := parser.Parse(info, e.include...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -93,6 +94,7 @@ func (e *listCmd) Flags() *flag.FlagSet {
|
||||||
if e.FlagSet == nil {
|
if e.FlagSet == nil {
|
||||||
e.FlagSet = flag.NewFlagSet("list", flag.ExitOnError)
|
e.FlagSet = flag.NewFlagSet("list", flag.ExitOnError)
|
||||||
e.BoolVar(&e.json, "json", false, "prints in JSON format")
|
e.BoolVar(&e.json, "json", false, "prints in JSON format")
|
||||||
|
e.Var(&e.include, "include", "packages the specified file or directory")
|
||||||
}
|
}
|
||||||
e.Usage = Usage(os.Stderr, e.FlagSet)
|
e.Usage = Usage(os.Stderr, e.FlagSet)
|
||||||
return e.FlagSet
|
return e.FlagSet
|
||||||
|
|
|
@ -14,13 +14,25 @@ import (
|
||||||
"github.com/markbates/pkger/pkging/pkgutil"
|
"github.com/markbates/pkger/pkging/pkgutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type slice []string
|
||||||
|
|
||||||
|
func (i slice) String() string {
|
||||||
|
return fmt.Sprintf("%s", []string(i))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *slice) Set(value string) error {
|
||||||
|
*i = append(*i, value)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
const outName = "pkged.go"
|
const outName = "pkged.go"
|
||||||
|
|
||||||
type packCmd struct {
|
type packCmd struct {
|
||||||
*flag.FlagSet
|
*flag.FlagSet
|
||||||
out string
|
out string
|
||||||
help bool
|
help bool
|
||||||
subs []command
|
include slice
|
||||||
|
subs []command
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *packCmd) Name() string {
|
func (e *packCmd) Name() string {
|
||||||
|
@ -36,7 +48,7 @@ func (e *packCmd) Exec(args []string) error {
|
||||||
fp := filepath.Join(info.Dir, e.out, outName)
|
fp := filepath.Join(info.Dir, e.out, outName)
|
||||||
os.RemoveAll(fp)
|
os.RemoveAll(fp)
|
||||||
|
|
||||||
decls, err := parser.Parse(info)
|
decls, err := parser.Parse(info, e.include...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -92,6 +104,7 @@ func New() (*packCmd, error) {
|
||||||
c.FlagSet = flag.NewFlagSet("pkger", flag.ExitOnError)
|
c.FlagSet = flag.NewFlagSet("pkger", flag.ExitOnError)
|
||||||
c.BoolVar(&c.help, "h", false, "prints help information")
|
c.BoolVar(&c.help, "h", false, "prints help information")
|
||||||
c.StringVar(&c.out, "o", "", "output directory for pkged.go")
|
c.StringVar(&c.out, "o", "", "output directory for pkged.go")
|
||||||
|
c.Var(&c.include, "include", "packages the specified file or directory")
|
||||||
c.Usage = func() {
|
c.Usage = func() {
|
||||||
fmt.Fprintf(os.Stderr, "Usage:\n\n")
|
fmt.Fprintf(os.Stderr, "Usage:\n\n")
|
||||||
Usage(os.Stderr, c.FlagSet)()
|
Usage(os.Stderr, c.FlagSet)()
|
||||||
|
|
|
@ -10,7 +10,7 @@ import (
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
clean := func() {
|
clean := func() {
|
||||||
c := exec.Command("go", "mod", "tidy", "-v")
|
c := exec.Command("go", "mod", "tidy")
|
||||||
c.Stdout = os.Stdout
|
c.Stdout = os.Stdout
|
||||||
c.Stderr = os.Stderr
|
c.Stderr = os.Stderr
|
||||||
c.Stdin = os.Stdin
|
c.Stdin = os.Stdin
|
||||||
|
@ -18,6 +18,13 @@ func main() {
|
||||||
}
|
}
|
||||||
defer clean()
|
defer clean()
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
if err := recover(); err != nil {
|
||||||
|
clean()
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
if err := run(); err != nil {
|
if err := run(); err != nil {
|
||||||
clean()
|
clean()
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -20,7 +21,7 @@ func run(n string, args ...string) ([]byte, error) {
|
||||||
c.Stderr = bb
|
c.Stderr = bb
|
||||||
err := c.Run()
|
err := c.Run()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("%w: %s", err, bb)
|
return nil, fmt.Errorf("%w: %q: %s", err, strings.Join(c.Args, " "), bb)
|
||||||
}
|
}
|
||||||
|
|
||||||
return bb.Bytes(), nil
|
return bb.Bytes(), nil
|
||||||
|
|
13
here/pkg.go
13
here/pkg.go
|
@ -2,8 +2,7 @@ package here
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"path"
|
"fmt"
|
||||||
"strings"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Package attempts to gather info for the requested package.
|
// Package attempts to gather info for the requested package.
|
||||||
|
@ -18,14 +17,12 @@ import (
|
||||||
func Package(p string) (Info, error) {
|
func Package(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
|
||||||
|
if len(p) == 0 || p == "." {
|
||||||
|
return i, fmt.Errorf("missing package name")
|
||||||
|
}
|
||||||
b, err := run("go", "list", "-json", "-find", p)
|
b, err := run("go", "list", "-json", "-find", p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if !strings.Contains(err.Error(), "can't load package: package") {
|
return i, err
|
||||||
return i, err
|
|
||||||
}
|
|
||||||
|
|
||||||
p, _ = path.Split(p)
|
|
||||||
return Package(p)
|
|
||||||
}
|
}
|
||||||
if err := json.Unmarshal(b, &i); err != nil {
|
if err := json.Unmarshal(b, &i); err != nil {
|
||||||
return i, err
|
return i, err
|
||||||
|
|
|
@ -0,0 +1,57 @@
|
||||||
|
package parser
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"go/token"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ Decl = IncludeDecl{}
|
||||||
|
|
||||||
|
type IncludeDecl struct {
|
||||||
|
file *File
|
||||||
|
pos token.Position
|
||||||
|
value string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d IncludeDecl) String() string {
|
||||||
|
return fmt.Sprintf("pkger.Include(%q)", d.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d IncludeDecl) MarshalJSON() ([]byte, error) {
|
||||||
|
return json.Marshal(map[string]interface{}{
|
||||||
|
"type": "pkger.Include",
|
||||||
|
"file": d.file,
|
||||||
|
"pos": d.pos,
|
||||||
|
"value": d.value,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d IncludeDecl) File() (*File, error) {
|
||||||
|
if d.file == nil {
|
||||||
|
return nil, os.ErrNotExist
|
||||||
|
}
|
||||||
|
return d.file, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d IncludeDecl) Position() (token.Position, error) {
|
||||||
|
return d.pos, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d IncludeDecl) Value() (string, error) {
|
||||||
|
if d.value == "" {
|
||||||
|
return "", os.ErrNotExist
|
||||||
|
}
|
||||||
|
return d.value, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d IncludeDecl) Files(virtual map[string]string) ([]*File, error) {
|
||||||
|
od := OpenDecl{
|
||||||
|
file: d.file,
|
||||||
|
pos: d.pos,
|
||||||
|
value: d.value,
|
||||||
|
}
|
||||||
|
|
||||||
|
return od.Files(virtual)
|
||||||
|
}
|
|
@ -70,6 +70,7 @@ func (d OpenDecl) Files(virtual map[string]string) ([]*File, error) {
|
||||||
}
|
}
|
||||||
return wd.Files(virtual)
|
return wd.Files(virtual)
|
||||||
}
|
}
|
||||||
|
|
||||||
var files []*File
|
var files []*File
|
||||||
files = append(files, d.file)
|
files = append(files, d.file)
|
||||||
|
|
||||||
|
|
|
@ -16,15 +16,32 @@ import (
|
||||||
|
|
||||||
var defaultIgnoredFolders = []string{".", "_", "vendor", "node_modules", "testdata"}
|
var defaultIgnoredFolders = []string{".", "_", "vendor", "node_modules", "testdata"}
|
||||||
|
|
||||||
func Parse(her here.Info) (Decls, error) {
|
func New(her here.Info) (*Parser, error) {
|
||||||
|
return &Parser{
|
||||||
|
Info: her,
|
||||||
|
decls: map[string]Decls{},
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type Parser struct {
|
||||||
|
here.Info
|
||||||
|
decls map[string]Decls
|
||||||
|
once sync.Once
|
||||||
|
includes []string
|
||||||
|
err error
|
||||||
|
}
|
||||||
|
|
||||||
|
func Parse(her here.Info, includes ...string) (Decls, error) {
|
||||||
p, err := New(her)
|
p, err := New(her)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
p.includes = includes
|
||||||
|
|
||||||
return p.Decls()
|
return p.Decls()
|
||||||
}
|
}
|
||||||
|
|
||||||
func ParseSource(source Source, mode parser.Mode) (*ParsedSource, error) {
|
func (p *Parser) ParseSource(source Source, mode parser.Mode) (*ParsedSource, error) {
|
||||||
pf := &ParsedSource{
|
pf := &ParsedSource{
|
||||||
Source: source,
|
Source: source,
|
||||||
FileSet: token.NewFileSet(),
|
FileSet: token.NewFileSet(),
|
||||||
|
@ -45,7 +62,7 @@ func ParseSource(source Source, mode parser.Mode) (*ParsedSource, error) {
|
||||||
return pf, nil
|
return pf, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func ParseFile(abs string, mode parser.Mode) (*ParsedSource, error) {
|
func (p *Parser) ParseFile(abs string, mode parser.Mode) (*ParsedSource, error) {
|
||||||
s := Source{
|
s := Source{
|
||||||
Abs: abs,
|
Abs: abs,
|
||||||
}
|
}
|
||||||
|
@ -68,10 +85,10 @@ func ParseFile(abs string, mode parser.Mode) (*ParsedSource, error) {
|
||||||
|
|
||||||
s.Path, err = s.Here.Parse(strings.TrimPrefix(abs, dir))
|
s.Path, err = s.Here.Parse(strings.TrimPrefix(abs, dir))
|
||||||
|
|
||||||
return ParseSource(s, 0)
|
return p.ParseSource(s, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func ParseDir(abs string, mode parser.Mode) ([]*ParsedSource, error) {
|
func (p *Parser) ParseDir(abs string, mode parser.Mode) ([]*ParsedSource, error) {
|
||||||
info, err := os.Stat(abs)
|
info, err := os.Stat(abs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -116,19 +133,6 @@ func ParseDir(abs string, mode parser.Mode) ([]*ParsedSource, error) {
|
||||||
|
|
||||||
return srcs, nil
|
return srcs, nil
|
||||||
}
|
}
|
||||||
func New(her here.Info) (*Parser, error) {
|
|
||||||
return &Parser{
|
|
||||||
Info: her,
|
|
||||||
decls: map[string]Decls{},
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type Parser struct {
|
|
||||||
here.Info
|
|
||||||
decls map[string]Decls
|
|
||||||
once sync.Once
|
|
||||||
err error
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Parser) Decls() (Decls, error) {
|
func (p *Parser) Decls() (Decls, error) {
|
||||||
if err := p.parse(); err != nil {
|
if err := p.parse(); err != nil {
|
||||||
|
@ -139,6 +143,7 @@ func (p *Parser) Decls() (Decls, error) {
|
||||||
orderedNames := []string{
|
orderedNames := []string{
|
||||||
"MkdirAll",
|
"MkdirAll",
|
||||||
"Create",
|
"Create",
|
||||||
|
"Include",
|
||||||
"Stat",
|
"Stat",
|
||||||
"Open",
|
"Open",
|
||||||
"Dir",
|
"Dir",
|
||||||
|
@ -166,12 +171,18 @@ func (p *Parser) Parse() error {
|
||||||
|
|
||||||
func (p *Parser) parse() error {
|
func (p *Parser) parse() error {
|
||||||
p.decls = map[string]Decls{}
|
p.decls = map[string]Decls{}
|
||||||
|
|
||||||
root := p.Dir
|
root := p.Dir
|
||||||
|
|
||||||
|
if err := p.parseIncludes(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
fi, err := os.Stat(root)
|
fi, err := os.Stat(root)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if !fi.IsDir() {
|
if !fi.IsDir() {
|
||||||
return fmt.Errorf("%q is not a directory", root)
|
return fmt.Errorf("%q is not a directory", root)
|
||||||
}
|
}
|
||||||
|
@ -192,7 +203,7 @@ func (p *Parser) parse() error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
srcs, err := ParseDir(path, 0)
|
srcs, err := p.ParseDir(path, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("%w: %s", err, path)
|
return fmt.Errorf("%w: %s", err, path)
|
||||||
}
|
}
|
||||||
|
@ -212,3 +223,33 @@ func (p *Parser) parse() error {
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *Parser) parseIncludes() error {
|
||||||
|
for _, i := range p.includes {
|
||||||
|
pt, err := p.Info.Parse(i)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
her := p.Info
|
||||||
|
if pt.Pkg != her.ImportPath {
|
||||||
|
her, err = here.Package(pt.Pkg)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abs := filepath.Join(her.Module.Dir, pt.Name)
|
||||||
|
|
||||||
|
f := &File{
|
||||||
|
Abs: abs,
|
||||||
|
Path: pt,
|
||||||
|
Here: her,
|
||||||
|
}
|
||||||
|
p.decls["Include"] = append(p.decls["Include"], IncludeDecl{
|
||||||
|
value: i,
|
||||||
|
file: f,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
@ -36,7 +36,46 @@ func Test_Parser_Ref(t *testing.T) {
|
||||||
|
|
||||||
files, err := res.Files()
|
files, err := res.Files()
|
||||||
r.NoError(err)
|
r.NoError(err)
|
||||||
r.Len(files, 23)
|
r.Len(files, 25)
|
||||||
|
|
||||||
|
for _, f := range files {
|
||||||
|
if f.Path.Pkg == ref.Module.Path {
|
||||||
|
r.True(strings.HasPrefix(f.Abs, ref.Dir), "%q %q", f.Abs, ref.Dir)
|
||||||
|
} else {
|
||||||
|
r.False(strings.HasPrefix(f.Abs, ref.Dir), "%q %q", f.Abs, ref.Dir)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_Parser_Ref_Include(t *testing.T) {
|
||||||
|
defer func() {
|
||||||
|
c := exec.Command("go", "mod", "tidy", "-v")
|
||||||
|
c.Run()
|
||||||
|
}()
|
||||||
|
r := require.New(t)
|
||||||
|
|
||||||
|
here.ClearCache()
|
||||||
|
ref, err := pkgtest.NewRef()
|
||||||
|
r.NoError(err)
|
||||||
|
defer os.RemoveAll(ref.Dir)
|
||||||
|
|
||||||
|
disk, err := stdos.New(ref.Info)
|
||||||
|
r.NoError(err)
|
||||||
|
|
||||||
|
_, err = pkgtest.LoadFiles("/", ref, disk)
|
||||||
|
r.NoError(err)
|
||||||
|
|
||||||
|
res, err := Parse(ref.Info, "github.com/gobuffalo/buffalo:/app.go")
|
||||||
|
|
||||||
|
r.NoError(err)
|
||||||
|
|
||||||
|
files, err := res.Files()
|
||||||
|
r.NoError(err)
|
||||||
|
// t.FailNow()
|
||||||
|
|
||||||
|
l := len(files)
|
||||||
|
r.Equal(26, l)
|
||||||
|
// r.Len(files, 27)
|
||||||
|
|
||||||
for _, f := range files {
|
for _, f := range files {
|
||||||
if f.Path.Pkg == ref.Module.Path {
|
if f.Path.Pkg == ref.Module.Path {
|
||||||
|
|
|
@ -88,6 +88,14 @@ func (p *ParsedSource) parse() error {
|
||||||
value: value,
|
value: value,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
case "Include":
|
||||||
|
fn = func(f File, pos token.Position, value string) Decl {
|
||||||
|
return IncludeDecl{
|
||||||
|
file: &f,
|
||||||
|
pos: pos,
|
||||||
|
value: value,
|
||||||
|
}
|
||||||
|
}
|
||||||
case "Stat":
|
case "Stat":
|
||||||
fn = func(f File, pos token.Position, value string) Decl {
|
fn = func(f File, pos token.Position, value string) Decl {
|
||||||
return StatDecl{
|
return StatDecl{
|
||||||
|
|
3
pkger.go
3
pkger.go
|
@ -95,3 +95,6 @@ func Remove(name string) error {
|
||||||
func RemoveAll(name string) error {
|
func RemoveAll(name string) error {
|
||||||
return impl().RemoveAll(name)
|
return impl().RemoveAll(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Include is a no-op that directs the pkger tool to include the desired file or folder.
|
||||||
|
func Include(name string) {}
|
||||||
|
|
|
@ -2,9 +2,6 @@ module app
|
||||||
|
|
||||||
go 1.13
|
go 1.13
|
||||||
|
|
||||||
require (
|
require github.com/markbates/pkger v0.0.0
|
||||||
github.com/gobuffalo/buffalo v0.15.0 // indirect
|
|
||||||
github.com/markbates/pkger v0.0.0
|
|
||||||
)
|
|
||||||
|
|
||||||
replace github.com/markbates/pkger => ../../../../
|
replace github.com/markbates/pkger => ../../../../
|
||||||
|
|
|
@ -12,6 +12,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
pkger.Include("/web")
|
||||||
if err := run(); err != nil {
|
if err := run(); err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,7 @@ func Test_Stuff(t *testing.T) {
|
||||||
decls, err := parser.Parse(ref.Info)
|
decls, err := parser.Parse(ref.Info)
|
||||||
r.NoError(err)
|
r.NoError(err)
|
||||||
|
|
||||||
r.Len(decls, 10)
|
r.Len(decls, 11)
|
||||||
|
|
||||||
files, err := decls.Files()
|
files, err := decls.Files()
|
||||||
r.NoError(err)
|
r.NoError(err)
|
||||||
|
@ -42,7 +42,7 @@ func Test_Stuff(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
r.Len(files, 23)
|
r.Len(files, 25)
|
||||||
|
|
||||||
bb := &bytes.Buffer{}
|
bb := &bytes.Buffer{}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue