move me over

This commit is contained in:
Mark Bates 2019-07-31 11:53:36 -04:00
parent a40fcc3eeb
commit 0f102bc1e8
11 changed files with 241 additions and 41 deletions

View File

@ -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=

View File

@ -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)

View File

@ -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
View File

@ -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
} }

33
file_test.go Normal file
View File

@ -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
View File

@ -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
View File

@ -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=

50
http_test.go Normal file
View File

@ -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())
}

View File

@ -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 {

View File

@ -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 {

View File

@ -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))
} }