Embed static files in Go binaries (replacement for gobuffalo/packr)
Go to file
Mark Bates c69a63df8d version bump: v0.12.0 2019-11-11 17:27:36 -05:00
cmd/pkger remove out file if packing panics 2019-11-11 16:46:12 -05:00
examples fix stat example 2019-11-01 16:22:08 -04:00
here Adds -include flag and pkger.Include directive fixes #28 2019-11-11 16:01:05 -05:00
internal remove hepa dep 2019-10-16 10:24:05 -04:00
parser Adds -include flag and pkger.Include directive fixes #28 2019-11-11 16:01:05 -05:00
pkging docs 2019-11-11 17:21:59 -05:00
.gitignore hey brett, you know what time it is? 2019-10-18 16:29:35 -04:00
.goreleaser.yml generated goreleaser 2019-10-18 16:37:25 -04:00
.goreleaser.yml.plush version bump: v0.1.0 2019-10-18 16:37:25 -04:00
LICENSE init 2019-07-30 12:12:21 -04:00
Makefile Adds -include flag and pkger.Include directive fixes #28 2019-11-11 16:01:05 -05:00
README.md version bump: v0.12.0 2019-11-11 17:27:36 -05:00
SHOULDERS.md version bump: v0.1.0 2019-10-18 16:32:45 -04:00
apply.go Adds -include flag and pkger.Include directive fixes #28 2019-11-11 16:01:05 -05:00
apply_test.go thats what i get 2019-09-21 18:00:53 -04:00
azure-pipelines.yml a self-made mug is hard to break 2019-10-31 11:12:18 -04:00
azure-tests.yml prime the mod cache 2019-11-05 15:09:28 -05:00
go.mod more examples 2019-10-17 13:45:22 -04:00
go.sum more examples 2019-10-17 13:45:22 -04:00
pkger.go Adds -include flag and pkger.Include directive fixes #28 2019-11-11 16:01:05 -05:00
pkger_test.go Digging the "Dancing Queen" 2019-11-01 16:08:10 -04:00
version.go version bump: v0.12.0 2019-11-11 17:27:36 -05:00

README.md

Pkger

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.

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

CLI

Installation

$ go get github.com/markbates/pkger/cmd/pkger
$ pkger -h

Usage

$ pkger

The result will be a pkged.go file in the root of the module with the embedded information and the package name of the module.

// ./pkged.go
package <.>

// Pkger stuff here

The -o flag can be used specify the directory of the pkged.go file.

$ pkger -o cmd/reader

The result will be a pkged.go file in the cmd/reader folder with the embedded information and the package name of that folder.

// cmd/reader/pkged.go
package <reader>

// Pkger stuff here

Reference Application

The reference application for the README examples, as well as all testing, can be found at https://github.com/markbates/pkger/tree/master/pkging/pkgtest/testdata/ref.

├── actions
│   └── actions.go
├── assets
│   ├── css
│   │   ├── _buffalo.scss
│   │   └── application.scss
│   ├── images
│   │   ├── favicon.ico
│   │   └── logo.svg
│   └── js
│       └── application.js
├── go.mod
├── go.sum
├── locales
│   └── all.en-us.yaml
├── main.go
├── mod
│   └── mod.go
├── models
│   └── models.go
├── public
│   ├── assets
│   │   └── app.css
│   ├── images
│   │   └── img1.png
│   ├── index.html
│   └── robots.txt
├── templates
│   ├── _flash.plush.html
│   ├── application.plush.html
│   └── index.plush.html
└── web
    └── web.go

13 directories, 20 files

API Usage

Pkger's API is modeled on that of the os package in Go's standard library. This makes Pkger usage familiar to Go developers.

The two most important interfaces are github.com/markbates/pkger/pkging#Pkger and github.com/markbates/pkger/pkging#File.

type Pkger interface {
  Parse(p string) (Path, 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
  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)
}

These two interfaces, along with the os#FileInfo, provide the bulk of the API surface area.

Open

func run() error {
	f, err := pkger.Open("/public/index.html")
	if err != nil {
		return err
	}
	defer f.Close()

	info, err := f.Stat()
	if err != nil {
		return err
	}

	fmt.Println("Name: ", info.Name())
	fmt.Println("Size: ", info.Size())
	fmt.Println("Mode: ", info.Mode())
	fmt.Println("ModTime: ", info.ModTime())

	if _, err := io.Copy(os.Stdout, f); err != nil {
		return err
	}
	return nil
}

Stat

func run() error {
	info, err := pkger.Stat("/public/index.html")
	if err != nil {
		return err
	}

	fmt.Println("Name: ", info.Name())
	fmt.Println("Size: ", info.Size())
	fmt.Println("Mode: ", info.Mode())
	fmt.Println("ModTime: ", info.ModTime())

	return nil
}

Walk

func run() error {
	w := tabwriter.NewWriter(os.Stdout, 0, 0, 0, ' ', tabwriter.Debug)
	defer w.Flush()

	return pkger.Walk("/public", func(path string, info os.FileInfo, err error) error {
		if err != nil {
			return err
		}

		fmt.Fprintf(w,
			"%s \t %d \t %s \t %s \t\n",
			info.Name(),
			info.Size(),
			info.Mode(),
			info.ModTime().Format(time.RFC3339),
		)

		return nil
	})

}