mirror of https://github.com/markbates/pkger.git
move me over
This commit is contained in:
parent
a40fcc3eeb
commit
0f102bc1e8
|
@ -1,2 +1,10 @@
|
||||||
github.com/gobuffalo/here v0.2.0 h1:tbOsO8QVUL5MT4swc0JnqZ7IlUm09e6vXYxNSMhOYMw=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/gobuffalo/here v0.2.0/go.mod h1:2a6G14FaAKOGJMK/5UNa4Og/+iyFS5cq3MnlvFR7YDk=
|
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/gobuffalo/here v0.2.1 h1:YWZUvrHnxNCIY2nnHPnF5Ob99Z5Iq29wHioLgcY+2G0=
|
||||||
|
github.com/gobuffalo/here v0.2.1/go.mod h1:2a6G14FaAKOGJMK/5UNa4Og/+iyFS5cq3MnlvFR7YDk=
|
||||||
|
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.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
|
||||||
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
|
|
|
@ -1,32 +1,42 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var globalFlags = struct {
|
||||||
|
*flag.FlagSet
|
||||||
|
}{
|
||||||
|
FlagSet: flag.NewFlagSet("", flag.ContinueOnError),
|
||||||
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
||||||
type ex func([]string) error
|
type ex func([]string) error
|
||||||
|
|
||||||
|
var cmds = map[string]ex{
|
||||||
|
"walk": walk,
|
||||||
|
"read": read,
|
||||||
|
"info": info,
|
||||||
|
"serve": serve,
|
||||||
|
}
|
||||||
args := os.Args[1:]
|
args := os.Args[1:]
|
||||||
|
|
||||||
if len(args) == 0 {
|
if len(args) == 0 {
|
||||||
log.Fatal("does not compute")
|
log.Fatal("does not compute")
|
||||||
}
|
}
|
||||||
|
|
||||||
var fn ex
|
fn, ok := cmds[args[0]]
|
||||||
switch args[0] {
|
if !ok {
|
||||||
case "walk":
|
fmt.Fprintf(os.Stderr, "couldn't understand args %q\n\n", args)
|
||||||
fn = walk
|
fmt.Fprintf(os.Stderr, "the following is a list of available commands:\n\n")
|
||||||
case "read":
|
for k := range cmds {
|
||||||
fn = read
|
fmt.Fprintf(os.Stderr, "\t%s\n", k)
|
||||||
case "info":
|
|
||||||
fn = info
|
|
||||||
case "serve":
|
|
||||||
fn = serve
|
|
||||||
}
|
}
|
||||||
if fn == nil {
|
os.Exit(1)
|
||||||
log.Fatal(args)
|
|
||||||
}
|
}
|
||||||
if err := fn(args[1:]); err != nil {
|
if err := fn(args[1:]); err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
@ -8,29 +10,50 @@ import (
|
||||||
"github.com/markbates/pkger"
|
"github.com/markbates/pkger"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type readOptions struct {
|
||||||
|
*flag.FlagSet
|
||||||
|
JSON bool
|
||||||
|
}
|
||||||
|
|
||||||
|
var readFlags = func() *readOptions {
|
||||||
|
rd := &readOptions{}
|
||||||
|
fs := flag.NewFlagSet("read", flag.ExitOnError)
|
||||||
|
fs.BoolVar(&rd.JSON, "json", false, "print as JSON")
|
||||||
|
rd.FlagSet = fs
|
||||||
|
return rd
|
||||||
|
}()
|
||||||
|
|
||||||
func read(args []string) error {
|
func read(args []string) error {
|
||||||
|
if err := readFlags.Parse(args); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
args = readFlags.Args()
|
||||||
|
|
||||||
if len(args) == 0 {
|
if len(args) == 0 {
|
||||||
args = []string{"."}
|
args = []string{"."}
|
||||||
}
|
}
|
||||||
for _, a := range args {
|
for _, a := range args {
|
||||||
fmt.Printf("### cmd/pkger/read.go:16 a (%T) -> %q %+v\n", a, a, a)
|
|
||||||
f, err := pkger.Open(a)
|
f, err := pkger.Open(a)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer f.Close()
|
defer f.Close()
|
||||||
|
|
||||||
fmt.Println(f.Path())
|
|
||||||
|
|
||||||
fi, err := f.Stat()
|
fi, err := f.Stat()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if fi.IsDir() {
|
if fi.IsDir() && !readFlags.JSON {
|
||||||
return fmt.Errorf("can not read a dir %s", a)
|
return fmt.Errorf("can not read a dir %s", a)
|
||||||
}
|
}
|
||||||
|
if readFlags.JSON {
|
||||||
|
err = json.NewEncoder(os.Stdout).Encode(f)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
_, err = io.Copy(os.Stdout, f)
|
_, err = io.Copy(os.Stdout, f)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
75
file.go
75
file.go
|
@ -3,10 +3,10 @@ package pkger
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/gobuffalo/here"
|
"github.com/gobuffalo/here"
|
||||||
|
@ -23,6 +23,59 @@ type File struct {
|
||||||
Source io.ReadCloser
|
Source io.ReadCloser
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (f File) MarshalJSON() ([]byte, error) {
|
||||||
|
m := map[string]interface{}{}
|
||||||
|
m["info"] = f.info
|
||||||
|
m["her"] = f.her
|
||||||
|
m["path"] = f.path
|
||||||
|
m["index"] = f.index
|
||||||
|
return json.Marshal(m)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *File) UnmarshalJSON(b []byte) error {
|
||||||
|
m := map[string]json.RawMessage{}
|
||||||
|
if err := json.Unmarshal(b, &m); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
info, ok := m["info"]
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("missing info")
|
||||||
|
}
|
||||||
|
f.info = &FileInfo{}
|
||||||
|
if err := json.Unmarshal(info, f.info); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
her, ok := m["her"]
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("missing her")
|
||||||
|
}
|
||||||
|
if err := json.Unmarshal(her, &f.her); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
path, ok := m["path"]
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("missing path")
|
||||||
|
}
|
||||||
|
if err := json.Unmarshal(path, &f.path); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
ind, ok := m["index"]
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("missing index")
|
||||||
|
}
|
||||||
|
f.index = &index{
|
||||||
|
Files: map[Path]*File{},
|
||||||
|
}
|
||||||
|
if err := json.Unmarshal(ind, f.index); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (f *File) Open(name string) (http.File, error) {
|
func (f *File) Open(name string) (http.File, error) {
|
||||||
if f.index == nil {
|
if f.index == nil {
|
||||||
f.index = &index{
|
f.index = &index{
|
||||||
|
@ -38,7 +91,9 @@ func (f *File) Open(name string) (http.File, error) {
|
||||||
pt.Pkg = f.path.Pkg
|
pt.Pkg = f.path.Pkg
|
||||||
}
|
}
|
||||||
|
|
||||||
h := httpFile{}
|
h := httpFile{
|
||||||
|
crs: &byteCRS{bytes.NewReader(f.data)},
|
||||||
|
}
|
||||||
|
|
||||||
if pt == f.path {
|
if pt == f.path {
|
||||||
h.File = f
|
h.File = f
|
||||||
|
@ -52,18 +107,19 @@ func (f *File) Open(name string) (http.File, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(f.data) > 0 {
|
if len(f.data) > 0 {
|
||||||
h.crs = &byteCRS{bytes.NewReader(f.data)}
|
|
||||||
return h, nil
|
return h, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
bf, err := os.Open(h.File.Path())
|
bf, err := f.her.Open(h.File.Path())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return h, err
|
return h, err
|
||||||
}
|
}
|
||||||
|
|
||||||
fi, err := bf.Stat()
|
fi, err := bf.Stat()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return h, err
|
return h, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if fi.IsDir() {
|
if fi.IsDir() {
|
||||||
return h, nil
|
return h, nil
|
||||||
}
|
}
|
||||||
|
@ -98,12 +154,7 @@ func (f File) Name() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f File) Path() string {
|
func (f File) Path() string {
|
||||||
dir := f.her.Dir
|
return f.her.FilePath(f.Name())
|
||||||
if filepath.Base(dir) == f.Name() {
|
|
||||||
return dir
|
|
||||||
}
|
|
||||||
fp := filepath.Join(dir, f.Name())
|
|
||||||
return fp
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f File) String() string {
|
func (f File) String() string {
|
||||||
|
@ -119,7 +170,7 @@ func (f *File) Read(p []byte) (int, error) {
|
||||||
return f.Source.Read(p)
|
return f.Source.Read(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
of, err := os.Open(f.Path())
|
of, err := f.her.Open(f.Path())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
@ -133,7 +184,7 @@ func (f *File) Read(p []byte) (int, error) {
|
||||||
//
|
//
|
||||||
// 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.
|
// 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) {
|
func (f *File) Readdir(count int) ([]os.FileInfo, error) {
|
||||||
of, err := os.Open(f.Path())
|
of, err := f.her.Open(f.Path())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
package pkger
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io/ioutil"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Test_File_Open(t *testing.T) {
|
||||||
|
r := require.New(t)
|
||||||
|
|
||||||
|
f, err := Open("/file_test.go")
|
||||||
|
r.NoError(err)
|
||||||
|
|
||||||
|
r.Equal("file_test.go", f.Name())
|
||||||
|
|
||||||
|
b, err := ioutil.ReadAll(f)
|
||||||
|
r.NoError(err)
|
||||||
|
r.Contains(string(b), "Test_File_Open")
|
||||||
|
r.NoError(f.Close())
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_File_Open_Dir(t *testing.T) {
|
||||||
|
r := require.New(t)
|
||||||
|
|
||||||
|
f, err := Open("/cmd")
|
||||||
|
r.NoError(err)
|
||||||
|
|
||||||
|
r.Equal("cmd", f.Name())
|
||||||
|
|
||||||
|
r.NoError(f.Close())
|
||||||
|
}
|
6
go.mod
6
go.mod
|
@ -2,4 +2,8 @@ module github.com/markbates/pkger
|
||||||
|
|
||||||
go 1.12
|
go 1.12
|
||||||
|
|
||||||
require github.com/gobuffalo/here v0.2.0
|
require (
|
||||||
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
|
github.com/gobuffalo/here v0.2.1
|
||||||
|
github.com/stretchr/testify v1.3.0
|
||||||
|
)
|
||||||
|
|
12
go.sum
12
go.sum
|
@ -1,2 +1,10 @@
|
||||||
github.com/gobuffalo/here v0.2.0 h1:tbOsO8QVUL5MT4swc0JnqZ7IlUm09e6vXYxNSMhOYMw=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/gobuffalo/here v0.2.0/go.mod h1:2a6G14FaAKOGJMK/5UNa4Og/+iyFS5cq3MnlvFR7YDk=
|
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/gobuffalo/here v0.2.1 h1:YWZUvrHnxNCIY2nnHPnF5Ob99Z5Iq29wHioLgcY+2G0=
|
||||||
|
github.com/gobuffalo/here v0.2.1/go.mod h1:2a6G14FaAKOGJMK/5UNa4Og/+iyFS5cq3MnlvFR7YDk=
|
||||||
|
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.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
|
||||||
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
package pkger
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
"net/http/httptest"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Test_HTTP_File(t *testing.T) {
|
||||||
|
r := require.New(t)
|
||||||
|
|
||||||
|
f, err := Open(".")
|
||||||
|
r.NoError(err)
|
||||||
|
|
||||||
|
ts := httptest.NewServer(http.FileServer(f))
|
||||||
|
defer ts.Close()
|
||||||
|
|
||||||
|
res, err := http.Get(ts.URL + "/cmd/pkger/main.go")
|
||||||
|
r.NoError(err)
|
||||||
|
r.Equal(200, res.StatusCode)
|
||||||
|
|
||||||
|
b, err := ioutil.ReadAll(res.Body)
|
||||||
|
r.NoError(err)
|
||||||
|
r.Contains(string(b), "does not compute")
|
||||||
|
|
||||||
|
r.NoError(f.Close())
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_HTTP_Dir(t *testing.T) {
|
||||||
|
r := require.New(t)
|
||||||
|
|
||||||
|
f, err := Open(".")
|
||||||
|
r.NoError(err)
|
||||||
|
|
||||||
|
ts := httptest.NewServer(http.FileServer(f))
|
||||||
|
defer ts.Close()
|
||||||
|
|
||||||
|
res, err := http.Get(ts.URL + "/cmd/pkger")
|
||||||
|
r.NoError(err)
|
||||||
|
r.Equal(200, res.StatusCode)
|
||||||
|
|
||||||
|
b, err := ioutil.ReadAll(res.Body)
|
||||||
|
r.NoError(err)
|
||||||
|
r.Contains(string(b), `<a href="main.go">main.go</a>`)
|
||||||
|
|
||||||
|
r.NoError(f.Close())
|
||||||
|
}
|
17
index.go
17
index.go
|
@ -1,6 +1,7 @@
|
||||||
package pkger
|
package pkger
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
@ -15,6 +16,22 @@ type index struct {
|
||||||
Files map[Path]*File
|
Files map[Path]*File
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (i index) MarshalJSON() ([]byte, error) {
|
||||||
|
m := map[string]interface{}{
|
||||||
|
"pkg": i.Pkg,
|
||||||
|
}
|
||||||
|
|
||||||
|
fm := map[string]File{}
|
||||||
|
|
||||||
|
for k, v := range i.Files {
|
||||||
|
fm[k.String()] = *v
|
||||||
|
}
|
||||||
|
|
||||||
|
m["files"] = fm
|
||||||
|
|
||||||
|
return json.Marshal(m)
|
||||||
|
}
|
||||||
|
|
||||||
func (i index) Walk(pt Path, wf WalkFunc) error {
|
func (i index) Walk(pt Path, wf WalkFunc) error {
|
||||||
|
|
||||||
if len(pt.Pkg) == 0 {
|
if len(pt.Pkg) == 0 {
|
||||||
|
|
4
path.go
4
path.go
|
@ -6,8 +6,8 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type Path struct {
|
type Path struct {
|
||||||
Pkg string
|
Pkg string `json:"pkg"`
|
||||||
Name string
|
Name string `json:"name"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p Path) String() string {
|
func (p Path) String() string {
|
||||||
|
|
|
@ -19,10 +19,6 @@ func Current() (here.Info, error) {
|
||||||
return Dir(".")
|
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) {
|
func Stat(info here.Info, p string) (os.FileInfo, error) {
|
||||||
return os.Stat(filepath.Join(info.Dir, p))
|
return os.Stat(filepath.Join(info.Dir, p))
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue