mirror of https://github.com/markbates/pkger.git
beyond belief
This commit is contained in:
parent
b2d6806f3f
commit
a40fcc3eeb
14
Makefile
14
Makefile
|
@ -1,8 +1,8 @@
|
|||
TAGS ?= ""
|
||||
GO_BIN ?= "go"
|
||||
|
||||
install:
|
||||
$(GO_BIN) install -tags ${TAGS} -v ./pkger/cmd/pkger
|
||||
install:
|
||||
cd ./cmd/pkger && $(GO_BIN) install -tags ${TAGS} -v .
|
||||
make tidy
|
||||
|
||||
tidy:
|
||||
|
@ -16,18 +16,18 @@ deps:
|
|||
$(GO_BIN) get -tags ${TAGS} -t ./...
|
||||
make tidy
|
||||
|
||||
build:
|
||||
build:
|
||||
$(GO_BIN) build -v .
|
||||
make tidy
|
||||
|
||||
test:
|
||||
test:
|
||||
$(GO_BIN) test -cover -tags ${TAGS} ./...
|
||||
make tidy
|
||||
|
||||
ci-deps:
|
||||
ci-deps:
|
||||
$(GO_BIN) get -tags ${TAGS} -t ./...
|
||||
|
||||
ci-test:
|
||||
ci-test:
|
||||
$(GO_BIN) test -tags ${TAGS} -race ./...
|
||||
|
||||
lint:
|
||||
|
@ -47,7 +47,7 @@ endif
|
|||
make install
|
||||
make tidy
|
||||
|
||||
release-test:
|
||||
release-test:
|
||||
$(GO_BIN) test -tags ${TAGS} -race ./...
|
||||
make tidy
|
||||
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
module github.com/markbates/pkger/cmd/pkger
|
||||
|
||||
go 1.12
|
||||
|
||||
require github.com/markbates/pkger v0.0.0
|
||||
|
||||
replace github.com/markbates/pkger => ../../
|
|
@ -0,0 +1,2 @@
|
|||
github.com/gobuffalo/here v0.2.0 h1:tbOsO8QVUL5MT4swc0JnqZ7IlUm09e6vXYxNSMhOYMw=
|
||||
github.com/gobuffalo/here v0.2.0/go.mod h1:2a6G14FaAKOGJMK/5UNa4Og/+iyFS5cq3MnlvFR7YDk=
|
|
@ -0,0 +1,40 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/markbates/pkger"
|
||||
)
|
||||
|
||||
func info(args []string) error {
|
||||
if len(args) == 0 {
|
||||
args = []string{"."}
|
||||
}
|
||||
for _, a := range args {
|
||||
f, err := pkger.Open(a)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
fi, err := f.Stat()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if fi.IsDir() {
|
||||
files, err := f.Readdir(-1)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, ff := range files {
|
||||
fmt.Println(pkger.NewFileInfo(ff))
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
fmt.Println(pkger.NewFileInfo(fi))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
)
|
||||
|
||||
func main() {
|
||||
type ex func([]string) error
|
||||
|
||||
args := os.Args[1:]
|
||||
|
||||
if len(args) == 0 {
|
||||
log.Fatal("does not compute")
|
||||
}
|
||||
|
||||
var fn ex
|
||||
switch args[0] {
|
||||
case "walk":
|
||||
fn = walk
|
||||
case "read":
|
||||
fn = read
|
||||
case "info":
|
||||
fn = info
|
||||
case "serve":
|
||||
fn = serve
|
||||
}
|
||||
if fn == nil {
|
||||
log.Fatal(args)
|
||||
}
|
||||
if err := fn(args[1:]); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
|
||||
"github.com/markbates/pkger"
|
||||
)
|
||||
|
||||
func read(args []string) error {
|
||||
if len(args) == 0 {
|
||||
args = []string{"."}
|
||||
}
|
||||
for _, a := range args {
|
||||
fmt.Printf("### cmd/pkger/read.go:16 a (%T) -> %q %+v\n", a, a, a)
|
||||
f, err := pkger.Open(a)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
fmt.Println(f.Path())
|
||||
|
||||
fi, err := f.Stat()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if fi.IsDir() {
|
||||
return fmt.Errorf("can not read a dir %s", a)
|
||||
}
|
||||
|
||||
_, err = io.Copy(os.Stdout, f)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
|
||||
"github.com/markbates/pkger"
|
||||
)
|
||||
|
||||
func serve(args []string) error {
|
||||
if len(args) == 0 {
|
||||
args = []string{"."}
|
||||
}
|
||||
f, err := pkger.Open(args[0])
|
||||
if err != nil {
|
||||
log.Fatal("1", err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
fmt.Println(f.Path())
|
||||
|
||||
return http.ListenAndServe(":3000", http.FileServer(f))
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/markbates/pkger"
|
||||
)
|
||||
|
||||
func walk(args []string) error {
|
||||
err := pkger.Walk(".", func(path pkger.Path, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Println(path)
|
||||
return nil
|
||||
})
|
||||
return err
|
||||
}
|
|
@ -0,0 +1,142 @@
|
|||
package pkger
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"github.com/gobuffalo/here"
|
||||
)
|
||||
|
||||
const timeFmt = time.RFC3339Nano
|
||||
|
||||
type File struct {
|
||||
info *FileInfo
|
||||
her here.Info
|
||||
path Path
|
||||
data []byte
|
||||
index *index
|
||||
Source io.ReadCloser
|
||||
}
|
||||
|
||||
func (f *File) Open(name string) (http.File, error) {
|
||||
if f.index == nil {
|
||||
f.index = &index{
|
||||
Files: map[Path]*File{},
|
||||
}
|
||||
}
|
||||
pt, err := Parse(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(pt.Pkg) == 0 {
|
||||
pt.Pkg = f.path.Pkg
|
||||
}
|
||||
|
||||
h := httpFile{}
|
||||
|
||||
if pt == f.path {
|
||||
h.File = f
|
||||
} else {
|
||||
of, err := f.index.Open(pt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer of.Close()
|
||||
h.File = of
|
||||
}
|
||||
|
||||
if len(f.data) > 0 {
|
||||
h.crs = &byteCRS{bytes.NewReader(f.data)}
|
||||
return h, nil
|
||||
}
|
||||
|
||||
bf, err := os.Open(h.File.Path())
|
||||
if err != nil {
|
||||
return h, err
|
||||
}
|
||||
fi, err := bf.Stat()
|
||||
if err != nil {
|
||||
return h, err
|
||||
}
|
||||
if fi.IsDir() {
|
||||
return h, nil
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
h.crs = bf
|
||||
return h, nil
|
||||
}
|
||||
|
||||
func (f File) Stat() (os.FileInfo, error) {
|
||||
if f.info == nil {
|
||||
return nil, os.ErrNotExist
|
||||
}
|
||||
return f.info, nil
|
||||
}
|
||||
|
||||
func (f *File) Close() error {
|
||||
if f.Source == nil {
|
||||
return nil
|
||||
}
|
||||
if c, ok := f.Source.(io.Closer); ok {
|
||||
return c.Close()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f File) Name() string {
|
||||
return f.info.Name()
|
||||
}
|
||||
|
||||
func (f File) Path() string {
|
||||
dir := f.her.Dir
|
||||
if filepath.Base(dir) == f.Name() {
|
||||
return dir
|
||||
}
|
||||
fp := filepath.Join(dir, f.Name())
|
||||
return fp
|
||||
}
|
||||
|
||||
func (f File) String() string {
|
||||
if f.info == nil {
|
||||
return ""
|
||||
}
|
||||
b, _ := json.MarshalIndent(f.info, "", " ")
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func (f *File) Read(p []byte) (int, error) {
|
||||
if f.Source != nil {
|
||||
return f.Source.Read(p)
|
||||
}
|
||||
|
||||
of, err := os.Open(f.Path())
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
f.Source = of
|
||||
return f.Source.Read(p)
|
||||
}
|
||||
|
||||
// Readdir reads the contents of the directory associated with file and returns a slice of up to n FileInfo values, as would be returned by Lstat, in directory order. Subsequent calls on the same file will yield further FileInfos.
|
||||
//
|
||||
// If n > 0, Readdir returns at most n FileInfo structures. In this case, if Readdir returns an empty slice, it will return a non-nil error explaining why. At the end of a directory, the error is io.EOF.
|
||||
//
|
||||
// If n <= 0, Readdir returns all the FileInfo from the directory in a single slice. In this case, if Readdir succeeds (reads all the way to the end of the directory), it returns the slice and a nil error. If it encounters an error before the end of the directory, Readdir returns the FileInfo read until that point and a non-nil error.
|
||||
func (f *File) Readdir(count int) ([]os.FileInfo, error) {
|
||||
of, err := os.Open(f.Path())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer of.Close()
|
||||
return of.Readdir(count)
|
||||
}
|
|
@ -0,0 +1,124 @@
|
|||
package pkger
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"os"
|
||||
"time"
|
||||
)
|
||||
|
||||
type FileInfo struct {
|
||||
name string
|
||||
size int64
|
||||
mode os.FileMode
|
||||
modTime time.Time
|
||||
isDir bool
|
||||
sys interface{}
|
||||
}
|
||||
|
||||
func (f *FileInfo) String() string {
|
||||
b, _ := json.MarshalIndent(f, "", " ")
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func (f *FileInfo) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(map[string]interface{}{
|
||||
"name": f.name,
|
||||
"size": f.size,
|
||||
"mode": f.mode,
|
||||
"modTime": f.modTime.Format(timeFmt),
|
||||
"isDir": f.isDir,
|
||||
"sys": f.sys,
|
||||
})
|
||||
}
|
||||
|
||||
// func (f *FileInfo) UnmarshalJSON(b []byte) error {
|
||||
// m := map[string]interface{}{}
|
||||
// if err := json.Unmarshal(b, &m); err != nil {
|
||||
// return err
|
||||
// }
|
||||
//
|
||||
// var ok bool
|
||||
//
|
||||
// f.name, ok = m["name"].(string)
|
||||
// if !ok {
|
||||
// return fmt.Errorf("could not determine name %q", m["name"])
|
||||
// }
|
||||
//
|
||||
// size, ok := m["size"].(float64)
|
||||
// if !ok {
|
||||
// return fmt.Errorf("could not determine size %q", m["size"])
|
||||
// }
|
||||
// f.size = int64(size)
|
||||
//
|
||||
// mode, ok := m["mode"].(float64)
|
||||
// if !ok {
|
||||
// return fmt.Errorf("could not determine mode %q", m["mode"])
|
||||
// }
|
||||
// f.mode = os.FileMode(mode)
|
||||
//
|
||||
// modTime, ok := m["modTime"].(string)
|
||||
// if !ok {
|
||||
// return fmt.Errorf("could not determine modTime %q", m["modTime"])
|
||||
// }
|
||||
// t, err := time.Parse(timeFmt, modTime)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
// f.modTime = t
|
||||
//
|
||||
// f.isDir, ok = m["isDir"].(bool)
|
||||
// if !ok {
|
||||
// return fmt.Errorf("could not determine isDir %q", m["isDir"])
|
||||
// }
|
||||
// f.sys = m["sys"]
|
||||
// return nil
|
||||
// }
|
||||
|
||||
func (f *FileInfo) Name() string {
|
||||
return f.name
|
||||
}
|
||||
|
||||
func (f *FileInfo) Size() int64 {
|
||||
return f.size
|
||||
}
|
||||
|
||||
func (f *FileInfo) Mode() os.FileMode {
|
||||
return f.mode
|
||||
}
|
||||
|
||||
func (f *FileInfo) ModTime() time.Time {
|
||||
return f.modTime
|
||||
}
|
||||
|
||||
func (f *FileInfo) IsDir() bool {
|
||||
return f.isDir
|
||||
}
|
||||
|
||||
func (f *FileInfo) Sys() interface{} {
|
||||
return f.sys
|
||||
}
|
||||
|
||||
var _ os.FileInfo = &FileInfo{}
|
||||
|
||||
func NewFileInfo(info os.FileInfo) *FileInfo {
|
||||
fi := &FileInfo{
|
||||
name: info.Name(),
|
||||
size: info.Size(),
|
||||
mode: info.Mode(),
|
||||
modTime: info.ModTime(),
|
||||
isDir: info.IsDir(),
|
||||
sys: info.Sys(),
|
||||
}
|
||||
return fi
|
||||
}
|
||||
|
||||
func WithName(name string, info os.FileInfo) *FileInfo {
|
||||
if ft, ok := info.(*FileInfo); ok {
|
||||
ft.name = name
|
||||
return ft
|
||||
}
|
||||
|
||||
fo := NewFileInfo(info)
|
||||
fo.name = name
|
||||
return fo
|
||||
}
|
2
go.mod
2
go.mod
|
@ -1,3 +1,5 @@
|
|||
module github.com/markbates/pkger
|
||||
|
||||
go 1.12
|
||||
|
||||
require github.com/gobuffalo/here v0.2.0
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
github.com/gobuffalo/here v0.2.0 h1:tbOsO8QVUL5MT4swc0JnqZ7IlUm09e6vXYxNSMhOYMw=
|
||||
github.com/gobuffalo/here v0.2.0/go.mod h1:2a6G14FaAKOGJMK/5UNa4Og/+iyFS5cq3MnlvFR7YDk=
|
|
@ -0,0 +1,45 @@
|
|||
package pkger
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
)
|
||||
|
||||
type crs interface {
|
||||
io.Closer
|
||||
io.Reader
|
||||
io.Seeker
|
||||
}
|
||||
|
||||
type byteCRS struct {
|
||||
*bytes.Reader
|
||||
}
|
||||
|
||||
func (byteCRS) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
var _ crs = &byteCRS{}
|
||||
|
||||
type httpFile struct {
|
||||
File *File
|
||||
crs
|
||||
}
|
||||
|
||||
func (h httpFile) Readdir(n int) ([]os.FileInfo, error) {
|
||||
if h.File == nil {
|
||||
return nil, os.ErrNotExist
|
||||
}
|
||||
return h.File.Readdir(n)
|
||||
}
|
||||
|
||||
func (h httpFile) Stat() (os.FileInfo, error) {
|
||||
if h.File == nil {
|
||||
return nil, os.ErrNotExist
|
||||
}
|
||||
return h.File.Stat()
|
||||
}
|
||||
|
||||
var _ http.File = &httpFile{}
|
|
@ -0,0 +1,116 @@
|
|||
package pkger
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/gobuffalo/here"
|
||||
"github.com/markbates/pkger/pkgs"
|
||||
)
|
||||
|
||||
type index struct {
|
||||
Pkg string
|
||||
Files map[Path]*File
|
||||
}
|
||||
|
||||
func (i index) Walk(pt Path, wf WalkFunc) error {
|
||||
|
||||
if len(pt.Pkg) == 0 {
|
||||
pt.Pkg = i.Pkg
|
||||
}
|
||||
if len(i.Files) > 0 {
|
||||
for k, v := range i.Files {
|
||||
if k.Pkg != pt.Pkg {
|
||||
continue
|
||||
}
|
||||
if err := wf(k, v.info, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var info here.Info
|
||||
var err error
|
||||
if pt.Pkg == "." {
|
||||
info, err = pkgs.Current()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
pt.Pkg = info.ImportPath
|
||||
}
|
||||
if info.IsZero() {
|
||||
info, err = pkgs.Pkg(pt.Pkg)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%s: %s", pt, err)
|
||||
}
|
||||
}
|
||||
|
||||
err = filepath.Walk(info.Dir, func(path string, fi os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
path = strings.TrimPrefix(path, info.Dir)
|
||||
pt, err := Parse(fmt.Sprintf("%s:%s", pt.Pkg, path))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return wf(pt, NewFileInfo(fi), err)
|
||||
})
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (i index) Open(pt Path) (*File, error) {
|
||||
if len(pt.Pkg) == 0 {
|
||||
pt.Pkg = i.Pkg
|
||||
}
|
||||
|
||||
f, ok := i.Files[pt]
|
||||
if !ok {
|
||||
return i.openDisk(pt)
|
||||
}
|
||||
return &File{
|
||||
info: f.info,
|
||||
path: f.path,
|
||||
data: f.data,
|
||||
her: f.her,
|
||||
index: &index{
|
||||
Files: map[Path]*File{},
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (i index) openDisk(pt Path) (*File, error) {
|
||||
if len(pt.Pkg) == 0 {
|
||||
pt.Pkg = i.Pkg
|
||||
}
|
||||
info, err := pkgs.Pkg(pt.Pkg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fp := info.Dir
|
||||
if len(pt.Name) > 0 {
|
||||
fp = filepath.Join(fp, pt.Name)
|
||||
}
|
||||
|
||||
fi, err := os.Stat(fp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
f := &File{
|
||||
info: WithName(pt.Name, NewFileInfo(fi)),
|
||||
her: info,
|
||||
path: pt,
|
||||
index: &index{
|
||||
Files: map[Path]*File{},
|
||||
},
|
||||
}
|
||||
return f, nil
|
||||
}
|
||||
|
||||
var rootIndex = &index{
|
||||
Files: map[Path]*File{},
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/markbates/pkger"
|
||||
)
|
||||
|
||||
func main() {
|
||||
f, err := pkger.Open("github.com/gobuffalo/buffalo:/server.go")
|
||||
if err != nil {
|
||||
log.Fatal("1", err)
|
||||
}
|
||||
|
||||
defer f.Close()
|
||||
|
||||
fi, err := f.Stat()
|
||||
if err != nil {
|
||||
log.Fatal("2", err)
|
||||
}
|
||||
|
||||
fmt.Println(fi)
|
||||
|
||||
io.Copy(os.Stdout, f)
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/markbates/pkger"
|
||||
)
|
||||
|
||||
func main() {
|
||||
f, err := pkger.Open("github.com/gobuffalo/buffalo")
|
||||
if err != nil {
|
||||
log.Fatal("1", err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
fmt.Println(f.Path())
|
||||
|
||||
go func() {
|
||||
time.Sleep(1 * time.Second)
|
||||
res, err := http.Get("http://127.0.0.1:3000/app.go")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer res.Body.Close()
|
||||
|
||||
_, err = io.Copy(os.Stdout, res.Body)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
if res.StatusCode >= 300 {
|
||||
log.Fatal("code: ", res.StatusCode)
|
||||
}
|
||||
|
||||
}()
|
||||
|
||||
log.Fatal(http.ListenAndServe(":3000", http.FileServer(f)))
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/markbates/pkger"
|
||||
)
|
||||
|
||||
func main() {
|
||||
err := pkger.Walk("github.com/gobuffalo/buffalo", func(path pkger.Path, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Println(path)
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
package pkger
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type Path struct {
|
||||
Pkg string
|
||||
Name string
|
||||
}
|
||||
|
||||
func (p Path) String() string {
|
||||
if len(p.Pkg) == 0 {
|
||||
return p.Name
|
||||
}
|
||||
if len(p.Name) == 0 {
|
||||
return p.Pkg
|
||||
}
|
||||
return fmt.Sprintf("%s:/%s", p.Pkg, p.Name)
|
||||
}
|
||||
|
||||
func Parse(p string) (Path, error) {
|
||||
var pt Path
|
||||
res := strings.Split(p, ":")
|
||||
|
||||
if len(res) < 1 {
|
||||
return pt, fmt.Errorf("could not parse %q (%d)", res, len(res))
|
||||
}
|
||||
if len(res) == 1 {
|
||||
if strings.HasPrefix(res[0], "/") {
|
||||
pt.Name = res[0]
|
||||
} else {
|
||||
pt.Pkg = res[0]
|
||||
}
|
||||
} else {
|
||||
pt.Pkg = res[0]
|
||||
pt.Name = res[1]
|
||||
}
|
||||
pt.Name = strings.TrimPrefix(pt.Name, "/")
|
||||
pt.Pkg = strings.TrimPrefix(pt.Pkg, "/")
|
||||
return pt, nil
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
package pkger
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
func modRoot() (string, error) {
|
||||
c := exec.Command("go", "env", "GOMOD")
|
||||
b, err := c.CombinedOutput()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
b = bytes.TrimSpace(b)
|
||||
if len(b) == 0 {
|
||||
return "", fmt.Errorf("the `go env GOMOD` was empty/modules are required")
|
||||
}
|
||||
|
||||
return filepath.Dir(string(b)), nil
|
||||
}
|
||||
|
||||
func Getwd() (string, error) {
|
||||
return modRoot()
|
||||
}
|
||||
|
||||
func Open(p string) (*File, error) {
|
||||
pt, err := Parse(p)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return rootIndex.Open(pt)
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
module github.com/markbates/pkger/pkger/cmd/pkger
|
||||
|
||||
go 1.12
|
|
@ -1,7 +0,0 @@
|
|||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
fmt.Println("vim-go")
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package pkgs
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/gobuffalo/here"
|
||||
)
|
||||
|
||||
func Pkg(p string) (here.Info, error) {
|
||||
return here.Cache(p, here.Package)
|
||||
}
|
||||
|
||||
func Dir(p string) (here.Info, error) {
|
||||
return here.Cache(p, here.Dir)
|
||||
}
|
||||
|
||||
func Current() (here.Info, error) {
|
||||
return Dir(".")
|
||||
}
|
||||
|
||||
func Open(info here.Info, p string) (*os.File, error) {
|
||||
return os.Open(filepath.Join(info.Dir, p))
|
||||
}
|
||||
|
||||
func Stat(info here.Info, p string) (os.FileInfo, error) {
|
||||
return os.Stat(filepath.Join(info.Dir, p))
|
||||
}
|
Loading…
Reference in New Issue