forked from mirror/pkger
superstar
This commit is contained in:
parent
0cb6202706
commit
9bd3853a21
|
@ -0,0 +1,203 @@
|
||||||
|
# Pkger
|
||||||
|
|
||||||
|
[`github.com/markbates/pkger`](https://godoc.org/github.com/markbates/pkger) is a tool for embedding static files into Go binaries. It will, hopefully, be a replacement for [`github.com/gobuffalo/packr/v2`](https://godoc.org/github.com/gobuffalo/packr/v2).
|
||||||
|
|
||||||
|
## How it Works
|
||||||
|
|
||||||
|
Pkger is powered by the dark magic of Go Modules, so they're like, totally required.
|
||||||
|
|
||||||
|
With Go Modules pkger can resolve packages with accuracy. No more guessing and trying to
|
||||||
|
figure out build paths, GOPATHS, etc... for this tired old lad.
|
||||||
|
|
||||||
|
With the module's path correctly resolved, it can serve as the "root" directory for that
|
||||||
|
module, and all files in that module's directory are available.
|
||||||
|
|
||||||
|
Paths:
|
||||||
|
* Paths should use UNIX style paths:
|
||||||
|
`/cmd/pkger/main.go`
|
||||||
|
* If unspecified the path's package is assumed to be the current module.
|
||||||
|
* Packages can specified in at the beginning of a path with a `:` seperator.
|
||||||
|
github.com/markbates/pkger:/cmd/pkger/main.go
|
||||||
|
* There are no relative paths. All paths are absolute to the modules root.
|
||||||
|
|
||||||
|
```
|
||||||
|
"github.com/gobuffalo/buffalo:/go.mod" => $GOPATH/pkg/mod/github.com/gobuffalo/buffalo@v0.14.7/go.mod
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
Pkger's API is modeled on that of the [`os`](https://godoc.org/os) package in Go's standard library. This makes Pkger usage familiar to Go developers.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
```go
|
||||||
|
type Pkger interface {
|
||||||
|
Parse(p string) (Path, error)
|
||||||
|
Abs(p string) (string, error)
|
||||||
|
AbsPath(Path) (string, error)
|
||||||
|
Current() (here.Info, error)
|
||||||
|
Info(p string) (here.Info, error)
|
||||||
|
Create(name string) (File, error)
|
||||||
|
MkdirAll(p string, perm os.FileMode) error
|
||||||
|
Open(name string) (File, error)
|
||||||
|
Stat(name string) (os.FileInfo, error)
|
||||||
|
Walk(p string, wf filepath.WalkFunc) error
|
||||||
|
Remove(name string) error
|
||||||
|
RemoveAll(path string) error
|
||||||
|
}
|
||||||
|
|
||||||
|
type File interface {
|
||||||
|
Close() error
|
||||||
|
Abs() (string, error)
|
||||||
|
Info() here.Info
|
||||||
|
Name() string
|
||||||
|
Open(name string) (http.File, error)
|
||||||
|
Path() Path
|
||||||
|
Read(p []byte) (int, error)
|
||||||
|
Readdir(count int) ([]os.FileInfo, error)
|
||||||
|
Seek(offset int64, whence int) (int64, error)
|
||||||
|
Stat() (os.FileInfo, error)
|
||||||
|
Write(b []byte) (int, error)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash
|
||||||
|
├── go.mod
|
||||||
|
├── go.sum
|
||||||
|
├── main.go
|
||||||
|
├── public
|
||||||
|
│ ├── images
|
||||||
|
│ │ ├── mark-small.png
|
||||||
|
│ │ ├── mark.png
|
||||||
|
│ │ ├── mark_250px.png
|
||||||
|
│ │ └── mark_400px.png
|
||||||
|
│ └── index.html
|
||||||
|
└── templates
|
||||||
|
├── a.txt
|
||||||
|
└── b
|
||||||
|
└── b.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/markbates/pkger"
|
||||||
|
)
|
||||||
|
|
||||||
|
const host = ":3000"
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// get the currently running application's here.Info.
|
||||||
|
// this contains really, really, really useful information
|
||||||
|
// about your application, check it out. :)
|
||||||
|
// we don't need it for this example, but i thought it could
|
||||||
|
// be good to show.
|
||||||
|
current, err := pkger.Current()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("Walking files for %s\n", current.ImportPath)
|
||||||
|
// walk the files in this module. "/" is where the `go.mod` for this module is
|
||||||
|
err = pkger.Walk("/", func(path string, info os.FileInfo, err error) error {
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
fmt.Println("> ", path)
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// find the public directory with using the full pkger path <pkg:/path> to it:
|
||||||
|
// pkg - is the module/package you want to get a file from
|
||||||
|
// if pkg is empty then it is assumed to be current.ImportPath
|
||||||
|
// : - seperator between the module/package name, pkg, and the "file path"
|
||||||
|
// path - this is the ABSOLUTE path to the file/directory you want, as relative
|
||||||
|
// to the root of the module/package's go.mod file.
|
||||||
|
dir, err := pkger.Open("github.com/markbates/pkger/examples/app:/public")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
// don't forget to close the file later
|
||||||
|
defer dir.Close()
|
||||||
|
|
||||||
|
fmt.Printf("\nServing %q on %s\n", dir.Path(), host)
|
||||||
|
|
||||||
|
// serve the public directory on the host (":3000")
|
||||||
|
// just like using the os package you still need to use
|
||||||
|
// http.FileServer to serve a directory.
|
||||||
|
// you DON'T, however, need to use http.Dir all pkger files
|
||||||
|
// already implement that interface.
|
||||||
|
log.Fatal(http.ListenAndServe(host, logger(http.FileServer(dir))))
|
||||||
|
}
|
||||||
|
|
||||||
|
// logger will print out the requests as they come in, otherwise its a blank
|
||||||
|
// screen, and that's no fun.
|
||||||
|
func logger(h http.Handler) http.HandlerFunc {
|
||||||
|
return func(res http.ResponseWriter, req *http.Request) {
|
||||||
|
log.Println(req.Method, req.URL.String())
|
||||||
|
h.ServeHTTP(res, req)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Output Without Packing
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# compile the go binary as usual and run the app:
|
||||||
|
$ go build -v; ./app
|
||||||
|
|
||||||
|
Walking files for github.com/markbates/pkger/examples/app
|
||||||
|
> github.com/markbates/pkger/examples/app:/
|
||||||
|
> github.com/markbates/pkger/examples/app:/.gitignore
|
||||||
|
> github.com/markbates/pkger/examples/app:/go.mod
|
||||||
|
> github.com/markbates/pkger/examples/app:/go.sum
|
||||||
|
> github.com/markbates/pkger/examples/app:/main.go
|
||||||
|
> github.com/markbates/pkger/examples/app:/public
|
||||||
|
> github.com/markbates/pkger/examples/app:/public/images
|
||||||
|
> github.com/markbates/pkger/examples/app:/public/images/mark-small.png
|
||||||
|
> github.com/markbates/pkger/examples/app:/public/images/mark.png
|
||||||
|
> github.com/markbates/pkger/examples/app:/public/images/mark_250px.png
|
||||||
|
> github.com/markbates/pkger/examples/app:/public/images/mark_400px.png
|
||||||
|
> github.com/markbates/pkger/examples/app:/public/index.html
|
||||||
|
> github.com/markbates/pkger/examples/app:/templates
|
||||||
|
> github.com/markbates/pkger/examples/app:/templates/a.txt
|
||||||
|
> github.com/markbates/pkger/examples/app:/templates/b
|
||||||
|
> github.com/markbates/pkger/examples/app:/templates/b/b.txt
|
||||||
|
|
||||||
|
Serving "github.com/markbates/pkger/examples/app:/public" on :3000
|
||||||
|
2019/09/22 14:07:41 GET /
|
||||||
|
2019/09/22 14:07:41 GET /images/mark.png
|
||||||
|
```
|
||||||
|
|
||||||
|
### Output With Packing
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# run the pkger cli to generate a pkged.go file:
|
||||||
|
$ pkger
|
||||||
|
|
||||||
|
# compile the go binary as usual and run the app:
|
||||||
|
$ go build -v; ./app
|
||||||
|
|
||||||
|
Walking files for github.com/markbates/pkger/examples/app
|
||||||
|
> github.com/markbates/pkger/examples/app:/
|
||||||
|
> github.com/markbates/pkger/examples/app:/public
|
||||||
|
> github.com/markbates/pkger/examples/app:/public/images
|
||||||
|
> github.com/markbates/pkger/examples/app:/public/images/mark-small.png
|
||||||
|
> github.com/markbates/pkger/examples/app:/public/images/mark.png
|
||||||
|
> github.com/markbates/pkger/examples/app:/public/images/mark_250px.png
|
||||||
|
> github.com/markbates/pkger/examples/app:/public/images/mark_400px.png
|
||||||
|
> github.com/markbates/pkger/examples/app:/public/index.html
|
||||||
|
|
||||||
|
Serving "github.com/markbates/pkger/examples/app:/public" on :3000
|
||||||
|
2019/09/22 14:07:41 GET /
|
||||||
|
2019/09/22 14:07:41 GET /images/mark.png
|
||||||
|
```
|
12
apply.go
12
apply.go
|
@ -1,18 +1,14 @@
|
||||||
|
// +build !debug
|
||||||
|
|
||||||
package pkger
|
package pkger
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
|
||||||
|
|
||||||
"github.com/markbates/pkger/pkging"
|
"github.com/markbates/pkger/pkging"
|
||||||
"github.com/markbates/pkger/pkging/pkgutil"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var current pkging.Pkger
|
|
||||||
|
|
||||||
func Apply(pkg pkging.Pkger, err error) error {
|
func Apply(pkg pkging.Pkger, err error) error {
|
||||||
if err := pkgutil.Dump(os.Stdout, pkg); err != nil {
|
gil.Lock()
|
||||||
return err
|
defer gil.Unlock()
|
||||||
}
|
|
||||||
current = pkging.Wrap(current, pkg)
|
current = pkging.Wrap(current, pkg)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
// +build debug
|
||||||
|
|
||||||
|
package pkger
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/markbates/pkger/pkging"
|
||||||
|
"github.com/markbates/pkger/pkging/pkgutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Apply(pkg pkging.Pkger, err error) error {
|
||||||
|
gil.Lock()
|
||||||
|
defer gil.Unlock()
|
||||||
|
if err := pkgutil.Dump(os.Stdout, pkg); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
current = pkging.Wrap(current, pkg)
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -2,45 +2,67 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"os"
|
||||||
|
|
||||||
"github.com/markbates/pkger"
|
"github.com/markbates/pkger"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
const host = ":3000"
|
||||||
mux := http.NewServeMux()
|
|
||||||
|
|
||||||
pub, err := pkger.Open(":/public")
|
func main() {
|
||||||
|
// get the currently running application's here.Info.
|
||||||
|
// this contains really, really, really useful information
|
||||||
|
// about your application, check it out. :)
|
||||||
|
// we don't need it for this example, but i thought it could
|
||||||
|
// be good to show.
|
||||||
|
current, err := pkger.Current()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
defer pub.Close()
|
|
||||||
|
|
||||||
fmt.Println(pub.Path())
|
fmt.Printf("Walking files for %s\n", current.ImportPath)
|
||||||
|
// walk the files in this module. "/" is where the `go.mod` for this module is
|
||||||
|
err = pkger.Walk("github.com/markbates/pkger/examples/app:/", func(path string, info os.FileInfo, err error) error {
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
fmt.Println("> ", path)
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
mux.Handle("/t", http.StripPrefix("/t", tmplHandler()))
|
// find the public directory with using the full pkger path <pkg:/path> to it:
|
||||||
mux.Handle("/", http.FileServer(pub))
|
// pkg - is the module/package you want to get a file from
|
||||||
|
// if pkg is empty then it is assumed to be current.ImportPath
|
||||||
|
// : - seperator between the module/package name, pkg, and the "file path"
|
||||||
|
// path - this is the ABSOLUTE path to the file/directory you want, as relative
|
||||||
|
// to the root of the module/package's go.mod file.
|
||||||
|
dir, err := pkger.Open("github.com/markbates/pkger/examples/app:/public")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
// don't forget to close the file later
|
||||||
|
defer dir.Close()
|
||||||
|
|
||||||
log.Fatal(http.ListenAndServe(":3000", logger(mux)))
|
fmt.Printf("\nServing %q on %s\n", dir.Path(), host)
|
||||||
|
|
||||||
|
// serve the public directory on the host (":3000")
|
||||||
|
// just like using the os package you still need to use
|
||||||
|
// http.FileServer to serve a directory.
|
||||||
|
// you DON'T, however, need to use http.Dir all pkger files
|
||||||
|
// already implement that interface.
|
||||||
|
log.Fatal(http.ListenAndServe(host, logger(http.FileServer(dir))))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// logger will print out the requests as they come in, otherwise its a blank
|
||||||
|
// screen, and that's no fun.
|
||||||
func logger(h http.Handler) http.HandlerFunc {
|
func logger(h http.Handler) http.HandlerFunc {
|
||||||
return func(res http.ResponseWriter, req *http.Request) {
|
return func(res http.ResponseWriter, req *http.Request) {
|
||||||
log.Println(req.Method, req.URL.String())
|
log.Println(req.Method, req.URL.String())
|
||||||
h.ServeHTTP(res, req)
|
h.ServeHTTP(res, req)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func tmplHandler() http.HandlerFunc {
|
|
||||||
return func(res http.ResponseWriter, req *http.Request) {
|
|
||||||
t, err := pkger.Open(":/templates/a.txt")
|
|
||||||
if err != nil {
|
|
||||||
http.Error(res, err.Error(), 500)
|
|
||||||
}
|
|
||||||
defer t.Close()
|
|
||||||
|
|
||||||
io.Copy(res, t)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
module github.com/markbates/pkger/examples/extfile
|
|
||||||
|
|
||||||
go 1.12
|
|
||||||
|
|
||||||
require github.com/markbates/pkger v0.0.0
|
|
||||||
|
|
||||||
replace github.com/markbates/pkger => ../../
|
|
||||||
|
|
|
@ -1,21 +0,0 @@
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
|
||||||
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/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
|
||||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
|
||||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
|
||||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
|
||||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
|
||||||
github.com/markbates/errx v1.1.0/go.mod h1:PLa46Oex9KNbVDZhKel8v1OT7hD5JZ2eI7AHhA0wswc=
|
|
||||||
github.com/markbates/pkger v0.0.0-20190830024022-c5e3a7de4d41 h1:bFEHpLBby7Qdvq92qw0TudeOfUKIZLcrweE/MMlNueI=
|
|
||||||
github.com/markbates/pkger v0.0.0-20190830024022-c5e3a7de4d41/go.mod h1:M9VeozwduQUCr6z54kJrK9JegpbOv4wiePSbgSbFOew=
|
|
||||||
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.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
|
||||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
|
||||||
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
|
||||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|
|
@ -1,28 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"log"
|
|
||||||
"os"
|
|
||||||
|
|
||||||
"github.com/markbates/pkger"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
f, err := pkger.Open("github.com/gobuffalo/meta:/go.mod")
|
|
||||||
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)
|
|
||||||
}
|
|
|
@ -1,8 +0,0 @@
|
||||||
module github.com/markbates/pkger/examples/httpserver
|
|
||||||
|
|
||||||
go 1.12
|
|
||||||
|
|
||||||
require github.com/markbates/pkger v0.0.0
|
|
||||||
|
|
||||||
replace github.com/markbates/pkger => ../../
|
|
||||||
|
|
|
@ -1,22 +0,0 @@
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
|
||||||
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/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
|
||||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
|
||||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
|
||||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
|
||||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
|
||||||
github.com/markbates/errx v1.1.0 h1:QDFeR+UP95dO12JgW+tgi2UVfo0V8YBHiUIOaeBPiEI=
|
|
||||||
github.com/markbates/errx v1.1.0/go.mod h1:PLa46Oex9KNbVDZhKel8v1OT7hD5JZ2eI7AHhA0wswc=
|
|
||||||
github.com/markbates/pkger v0.0.0-20190830024022-c5e3a7de4d41 h1:bFEHpLBby7Qdvq92qw0TudeOfUKIZLcrweE/MMlNueI=
|
|
||||||
github.com/markbates/pkger v0.0.0-20190830024022-c5e3a7de4d41/go.mod h1:M9VeozwduQUCr6z54kJrK9JegpbOv4wiePSbgSbFOew=
|
|
||||||
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.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
|
||||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
|
||||||
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
|
||||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|
|
@ -1,43 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"log"
|
|
||||||
"net/http"
|
|
||||||
"os"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/markbates/pkger"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
dir, err := pkger.Open(".:/public")
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal("1", err)
|
|
||||||
}
|
|
||||||
defer dir.Close()
|
|
||||||
|
|
||||||
fmt.Println(dir.Path())
|
|
||||||
|
|
||||||
go func() {
|
|
||||||
time.Sleep(1 * time.Second)
|
|
||||||
res, err := http.Get("http://127.0.0.1:3000/assets/radio.radio")
|
|
||||||
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.StripPrefix("/assets/", http.FileServer(dir))))
|
|
||||||
}
|
|
|
@ -1,35 +0,0 @@
|
||||||
I was tuning in the shine on the late night dial
|
|
||||||
Doing anything my radio advised
|
|
||||||
With every one of those late night stations
|
|
||||||
Playing songs bringing tears to my eyes
|
|
||||||
I was seriously thinking about hiding the receiver
|
|
||||||
When the switch broke 'cause it's old
|
|
||||||
They're saying things that I can hardly believe
|
|
||||||
They really think we're getting out of control
|
|
||||||
Radio is a sound salvation
|
|
||||||
Radio is cleaning up the nation
|
|
||||||
They say you better listen to the voice of reason
|
|
||||||
But they don't give you any choice 'cause they think that it's treason
|
|
||||||
So you had better do as you are told
|
|
||||||
You better listen to the radio
|
|
||||||
I wanna bite the hand that feeds me
|
|
||||||
I wanna bite that hand so badly
|
|
||||||
I want to make them wish they'd never seen me
|
|
||||||
Some of my friends sit around every evening
|
|
||||||
And they worry about the times ahead
|
|
||||||
But everybody else is overwhelmed by indifference
|
|
||||||
And the promise of an early bed
|
|
||||||
You either shut up or get cut up; they don't wanna hear about it
|
|
||||||
It's only inches on the reel-to-reel
|
|
||||||
And the radio is in the hands of such a lot of fools
|
|
||||||
Tryin' to anesthetize the way that you feel
|
|
||||||
Radio is a sound salvation
|
|
||||||
Radio is cleaning up the nation
|
|
||||||
They say you better listen to the voice of reason
|
|
||||||
But they don't give you any choice 'cause they think that it's treason
|
|
||||||
So you had better do as you are told
|
|
||||||
You better listen to the radio
|
|
||||||
Wonderful radio
|
|
||||||
Marvelous radio
|
|
||||||
Wonderful radio
|
|
||||||
Radio, radio
|
|
|
@ -1,8 +0,0 @@
|
||||||
module github.com/markbates/pkger/examples/walk
|
|
||||||
|
|
||||||
go 1.12
|
|
||||||
|
|
||||||
require github.com/markbates/pkger v0.0.0
|
|
||||||
|
|
||||||
replace github.com/markbates/pkger => ../../
|
|
||||||
|
|
|
@ -1,21 +0,0 @@
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
|
||||||
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/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
|
||||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
|
||||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
|
||||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
|
||||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
|
||||||
github.com/markbates/errx v1.1.0/go.mod h1:PLa46Oex9KNbVDZhKel8v1OT7hD5JZ2eI7AHhA0wswc=
|
|
||||||
github.com/markbates/pkger v0.0.0-20190830024022-c5e3a7de4d41 h1:bFEHpLBby7Qdvq92qw0TudeOfUKIZLcrweE/MMlNueI=
|
|
||||||
github.com/markbates/pkger v0.0.0-20190830024022-c5e3a7de4d41/go.mod h1:M9VeozwduQUCr6z54kJrK9JegpbOv4wiePSbgSbFOew=
|
|
||||||
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.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
|
||||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
|
||||||
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
|
||||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|
|
@ -1,26 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
"os"
|
|
||||||
|
|
||||||
"github.com/markbates/pkger"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
err := pkger.Walk("github.com/gobuffalo/envy", func(path pkger.Path, info os.FileInfo) error {
|
|
||||||
fmt.Println(path)
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
err = pkger.Walk("/", func(path pkger.Path, info os.FileInfo) error {
|
|
||||||
fmt.Println(path)
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -51,7 +51,6 @@ func Parse(her here.Info) (Results, error) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if info.IsDir() {
|
if info.IsDir() {
|
||||||
if _, err := os.Stat(filepath.Join(path, "go.mod")); err == nil {
|
if _, err := os.Stat(filepath.Join(path, "go.mod")); err == nil {
|
||||||
her, err = here.Dir(path)
|
her, err = here.Dir(path)
|
||||||
|
|
|
@ -32,7 +32,6 @@ func Test_Parser(t *testing.T) {
|
||||||
"github.com/markbates/pkger/examples/app:/public/images/mark_250px.png",
|
"github.com/markbates/pkger/examples/app:/public/images/mark_250px.png",
|
||||||
"github.com/markbates/pkger/examples/app:/public/images/mark_400px.png",
|
"github.com/markbates/pkger/examples/app:/public/images/mark_400px.png",
|
||||||
"github.com/markbates/pkger/examples/app:/public/index.html",
|
"github.com/markbates/pkger/examples/app:/public/index.html",
|
||||||
"github.com/markbates/pkger/examples/app:/templates/a.txt",
|
|
||||||
}
|
}
|
||||||
sort.Strings(exp)
|
sort.Strings(exp)
|
||||||
|
|
||||||
|
|
|
@ -186,7 +186,7 @@ func (v *visitor) evalSelector(expr *ast.CallExpr, sel *ast.SelectorExpr) error
|
||||||
switch sel.Sel.Name {
|
switch sel.Sel.Name {
|
||||||
case "Walk":
|
case "Walk":
|
||||||
if len(expr.Args) != 2 {
|
if len(expr.Args) != 2 {
|
||||||
return fmt.Errorf("`New` requires two arguments")
|
return fmt.Errorf("`Walk` requires two arguments")
|
||||||
}
|
}
|
||||||
|
|
||||||
zz := func(e ast.Expr) (string, error) {
|
zz := func(e ast.Expr) (string, error) {
|
||||||
|
|
46
pkger.go
46
pkger.go
|
@ -1,69 +1,87 @@
|
||||||
package pkger
|
package pkger
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"sync"
|
||||||
|
|
||||||
"github.com/markbates/pkger/here"
|
"github.com/markbates/pkger/here"
|
||||||
"github.com/markbates/pkger/pkging"
|
"github.com/markbates/pkger/pkging"
|
||||||
"github.com/markbates/pkger/pkging/stdos"
|
"github.com/markbates/pkger/pkging/stdos"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ = func() error {
|
var current pkging.Pkger
|
||||||
return Apply(stdos.New())
|
var gil = &sync.RWMutex{}
|
||||||
|
|
||||||
|
var disk = func() pkging.Pkger {
|
||||||
|
n, err := stdos.New()
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
}
|
||||||
|
return n
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
func impl() pkging.Pkger {
|
||||||
|
gil.RLock()
|
||||||
|
defer gil.RUnlock()
|
||||||
|
if current == nil {
|
||||||
|
return disk
|
||||||
|
}
|
||||||
|
return current
|
||||||
|
}
|
||||||
|
|
||||||
func Parse(p string) (pkging.Path, error) {
|
func Parse(p string) (pkging.Path, error) {
|
||||||
return current.Parse(p)
|
return impl().Parse(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
func Abs(p string) (string, error) {
|
func Abs(p string) (string, error) {
|
||||||
return current.Abs(p)
|
return impl().Abs(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
func AbsPath(p pkging.Path) (string, error) {
|
func AbsPath(p pkging.Path) (string, error) {
|
||||||
return current.AbsPath(p)
|
return impl().AbsPath(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
func Current() (here.Info, error) {
|
func Current() (here.Info, error) {
|
||||||
return current.Current()
|
return impl().Current()
|
||||||
}
|
}
|
||||||
|
|
||||||
func Info(p string) (here.Info, error) {
|
func Info(p string) (here.Info, error) {
|
||||||
return current.Info(p)
|
return impl().Info(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create creates the named file with mode 0666 (before umask) - It's actually 0644, truncating it if it already exists. If successful, methods on the returned File can be used for I/O; the associated file descriptor has mode O_RDWR.
|
// Create creates the named file with mode 0666 (before umask) - It's actually 0644, truncating it if it already exists. If successful, methods on the returned File can be used for I/O; the associated file descriptor has mode O_RDWR.
|
||||||
func Create(p string) (pkging.File, error) {
|
func Create(p string) (pkging.File, error) {
|
||||||
return current.Create(p)
|
return impl().Create(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MkdirAll creates a directory named path, along with any necessary parents, and returns nil, or else returns an error. The permission bits perm (before umask) are used for all directories that MkdirAll creates. If path is already a directory, MkdirAll does nothing and returns nil.
|
// MkdirAll creates a directory named path, along with any necessary parents, and returns nil, or else returns an error. The permission bits perm (before umask) are used for all directories that MkdirAll creates. If path is already a directory, MkdirAll does nothing and returns nil.
|
||||||
func MkdirAll(p string, perm os.FileMode) error {
|
func MkdirAll(p string, perm os.FileMode) error {
|
||||||
return current.MkdirAll(p, perm)
|
return impl().MkdirAll(p, perm)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Open opens the named file for reading. If successful, methods on the returned file can be used for reading; the associated file descriptor has mode O_RDONLY.
|
// Open opens the named file for reading. If successful, methods on the returned file can be used for reading; the associated file descriptor has mode O_RDONLY.
|
||||||
func Open(p string) (pkging.File, error) {
|
func Open(p string) (pkging.File, error) {
|
||||||
return current.Open(p)
|
return impl().Open(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stat returns a FileInfo describing the named file.
|
// Stat returns a FileInfo describing the named file.
|
||||||
func Stat(name string) (os.FileInfo, error) {
|
func Stat(name string) (os.FileInfo, error) {
|
||||||
return current.Stat(name)
|
return impl().Stat(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Walk walks the file tree rooted at root, calling walkFn for each file or directory in the tree, including root. All errors that arise visiting files and directories are filtered by walkFn. The files are walked in lexical order, which makes the output deterministic but means that for very large directories Walk can be inefficient. Walk does not follow symbolic links. - That is from the standard library. I know. Their grammar teachers can not be happy with them right now.
|
// Walk walks the file tree rooted at root, calling walkFn for each file or directory in the tree, including root. All errors that arise visiting files and directories are filtered by walkFn. The files are walked in lexical order, which makes the output deterministic but means that for very large directories Walk can be inefficient. Walk does not follow symbolic links. - That is from the standard library. I know. Their grammar teachers can not be happy with them right now.
|
||||||
func Walk(p string, wf filepath.WalkFunc) error {
|
func Walk(p string, wf filepath.WalkFunc) error {
|
||||||
return current.Walk(p, wf)
|
return impl().Walk(p, wf)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove removes the named file or (empty) directory.
|
// Remove removes the named file or (empty) directory.
|
||||||
func Remove(name string) error {
|
func Remove(name string) error {
|
||||||
return current.Remove(name)
|
return impl().Remove(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
// RemoveAll removes path and any children it contains. It removes everything it can but returns the first error it encounters. If the path does not exist, RemoveAll returns nil (no error).
|
// RemoveAll removes path and any children it contains. It removes everything it can but returns the first error it encounters. If the path does not exist, RemoveAll returns nil (no error).
|
||||||
func RemoveAll(name string) error {
|
func RemoveAll(name string) error {
|
||||||
return current.RemoveAll(name)
|
return impl().RemoveAll(name)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue