• This repository has been archived on 26/Jun/2022
  • Stars
    star
    3,412
  • Rank 13,111 (Top 0.3 %)
  • Language
    Go
  • License
    MIT License
  • Created over 7 years ago
  • Updated almost 3 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

The simple and easy way to embed static files into Go binaries.

NOTICE: Please consider migrating your projects to embed which is native file embedding feature of Go, or github.com/markbates/pkger. It has an idiomatic API, minimal dependencies, a stronger test suite (tested directly against the std lib counterparts), transparent tooling, and more.

https://blog.gobuffalo.io/introducing-pkger-static-file-embedding-in-go-1ce76dc79c65

Packr (v2)

GoDoc Actions Status

Packr is a simple solution for bundling static assets inside of Go binaries. Most importantly it does it in a way that is friendly to developers while they are developing.

At this moment, supported go versions are:

  • 1.16.x
  • 1.17.x

even though it may (or may not) working well with older versions.

Intro Video

To get an idea of the what and why of Packr, please enjoy this short video: https://vimeo.com/219863271.

Library Installation

Go 1.16 and above

$ go install github.com/gobuffalo/packr/[email protected]

or

$ go install github.com/gobuffalo/packr/v2@latest

Go 1.15 and below

$ go get -u github.com/gobuffalo/packr/...

Binary Installation

Go 1.16 and above

$ go install github.com/gobuffalo/packr/v2/[email protected]

or

$ go install github.com/gobuffalo/packr/v2/packr2@latest

Go 1.15 and below

$ go get -u github.com/gobuffalo/packr/packr2

New File Format FAQs

In version v2.0.0 the file format changed and is not backward compatible with the packr-v1.x library.

Can packr-v1.x read the new format?

No, it can not. Because of the way the new file format works porting it to packr-v1.x would be difficult. PRs are welcome though. :)

Can packr-v2.x read packr-v1.x files?

Yes it can, but that ability will eventually be phased out. Because of that we recommend moving to the new format.

Can packr-v2.x generate packr-v1.x files?

Yes it can, but that ability will eventually be phased out. Because of that we recommend moving to the new format.

The --legacy command is available on all commands that generate -packr.go files.

$ packr2 --legacy

Usage

In Code

The first step in using Packr is to create a new box. A box represents a folder on disk. Once you have a box you can get string or []byte representations of the file.

// set up a new box by giving it a name and an optional (relative) path to a folder on disk:
box := packr.New("My Box", "./templates")

// Get the string representation of a file, or an error if it doesn't exist:
html, err := box.FindString("index.html")

// Get the []byte representation of a file, or an error if it doesn't exist:
html, err := box.Find("index.html")

What is a Box?

A box represents a folder, and any sub-folders, on disk that you want to have access to in your binary. When compiling a binary using the packr2 CLI the contents of the folder will be converted into Go files that can be compiled inside of a "standard" go binary. Inside of the compiled binary the files will be read from memory. When working locally the files will be read directly off of disk. This is a seamless switch that doesn't require any special attention on your part.

Example

Assume the follow directory structure:

β”œβ”€β”€ main.go
└── templates
    β”œβ”€β”€ admin
    β”‚Β Β  └── index.html
    └── index.html

The following program will read the ./templates/admin/index.html file and print it out.

package main

import (
  "fmt"

  "github.com/gobuffalo/packr/v2"
)

func main() {
  box := packr.New("myBox", "./templates")

  s, err := box.FindString("admin/index.html")
  if err != nil {
    log.Fatal(err)
  }
  fmt.Println(s)
}

Development Made Easy

In order to get static files into a Go binary, those files must first be converted to Go code. To do that, Packr, ships with a few tools to help build binaries. See below.

During development, however, it is painful to have to keep running a tool to compile those files.

Packr uses the following resolution rules when looking for a file:

  1. Look for the file in-memory (inside a Go binary)
  2. Look for the file on disk (during development)

Because Packr knows how to fall through to the file system, developers don't need to worry about constantly compiling their static files into a binary. They can work unimpeded.

Packr takes file resolution a step further. When declaring a new box you use a relative path, ./templates. When Packr receives this call it calculates out the absolute path to that directory. By doing this it means you can be guaranteed that Packr can find your files correctly, even if you're not running in the directory that the box was created in. This helps with the problem of testing, where Go changes the pwd for each package, making relative paths difficult to work with. This is not a problem when using Packr.


Usage with HTTP

A box implements the http.FileSystem interface, meaning it can be used to serve static files.

package main

import (
	"net/http"

	"github.com/gobuffalo/packr/v2"
)

func main() {
	box := packr.New("someBoxName", "./templates")

	http.Handle("/", http.FileServer(box))
	http.ListenAndServe(":3000", nil)
}

Building a Binary

Before you build your Go binary, run the packr2 command first. It will look for all the boxes in your code and then generate .go files that pack the static files into bytes that can be bundled into the Go binary.

$ packr2

Then run your go build command like normal.

NOTE: It is not recommended to check-in these generated -packr.go files. They can be large, and can easily become out of date if not careful. It is recommended that you always run packr2 clean after running the packr2 tool.

Cleaning Up

When you're done it is recommended that you run the packr2 clean command. This will remove all of the generated files that Packr created for you.

$ packr2 clean

Why do you want to do this? Packr first looks to the information stored in these generated files, if the information isn't there it looks to disk. This makes it easy to work with in development.


Debugging

The packr2 command passes all arguments down to the underlying go command, this includes the -v flag to print out go build information. Packr looks for the -v flag, and will turn on its own verbose logging. This is very useful for trying to understand what the packr command is doing when it is run.


FAQ

Compilation Errors with Go Templates

Q: I have a program with Go template files, those files are named foo.go and look like the following:

// Copyright {{.Year}} {{.Author}}. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package {{.Project}}

When I run packr2 I get errors like:

expected 'IDENT', found '{'

A: Packr works by searching your .go files for github.com/gobuffalo/packr/v2#New or github.com/gobuffalo/packr/v2#NewBox calls. Because those files aren't "proper" Go files, Packr can't parse them to find the box declarations. To fix this you need to tell Packr to ignore those files when searching for boxes. A couple solutions to this problem are:

  • Name the files something else. The .tmpl extension is the idiomatic way of naming these types of files.
  • Rename the folder containing these files to start with an _, for example _templates. Packr, like Go, will ignore folders starting with the _ character when searching for boxes.

Dynamic Box Paths

Q: I need to set the path of a box using a variable, but packr.New("foo", myVar) doesn't work correctly.

A: Packr attempts to "automagically" set it's resolution directory when using github.com/gobuffalo/packr/v2#New, however, for dynamic paths you need to set it manually:

box := packr.New("foo", "|")
box.ResolutionDir = myVar

I don't want to pack files, but still use the Packr interface.

Q: I want to write code that using the Packr tools, but doesn't actually pack the files into my binary. How can I do that?

A: Using github.com/gobuffalo/packr/v2#Folder gives you back a *packr.Box that can be used as normal, but is excluded by the Packr tool when compiling.

Packr Finds No Boxes

Q: I run packr2 -v but it doesn't find my boxes:

DEBU[2019-03-18T18:48:52+01:00] *parser.Parser#NewFromRoots found prospects=0
DEBU[2019-03-18T18:48:52+01:00] found 0 boxes

A: Packr works by parsing .go files to find github.com/gobuffalo/packr/v2#Box and github.com/gobuffalo/packr/v2#NewBox declarations. If there aren't any .go in the folder that packr2 is run in it can not find those declarations. To fix this problem run the packr2 command in the directory containing your .go files.

Box Interfaces

Q: I want to be able to easily test my applications by passing in mock boxes. How do I do that?

A: Packr boxes and files conform to the interfaces found at github.com/gobuffalo/packd. Change your application to use those interfaces instead of the concrete Packr types.

// using concrete type
func myFunc(box *packr.Box) {}

// using interfaces
func myFunc(box packd.Box) {}

More Repositories

1

buffalo

Rapid Web Development w/ Go
Go
8,069
star
2

pop

A Tasty Treat For All Your Database Needs
Go
1,429
star
3

plush

The powerful template system that Go needs
Go
889
star
4

envy

Envy makes working with ENV variables in Go trivial.
Go
155
star
5

fizz

A Common DSL for Migrating Databases
Go
149
star
6

docs

The source for the Buffalo website
JavaScript
111
star
7

flect

An inflection engine for golang
Go
102
star
8

vuerecipe

A recipe for using Buffalo & Vue.js
Go
96
star
9

validate

This package provides a framework for writing validations for Go applications.
Go
95
star
10

velvet

A sweet velvety templating package
Go
73
star
11

genny

A framework for writing modular generators
Go
65
star
12

toodo

A Simple Todo Application Written in Buffalo
Go
60
star
13

tags

HTML tags in Go
Go
53
star
14

nulls

A collection of null types for the sql package
Go
44
star
15

buffalo-auth

Buffalo auth plugin helps adding username password authentication to your app
Go
41
star
16

authrecipe

A recipe for using Buffalo & Password Authentication
Go
29
star
17

suite

A test suite for Buffalo applications
Go
26
star
18

lush

Go
25
star
19

shoulders

SHOULDERS.md generator
Go
20
star
20

buffalo-pop

A plugin to use gobuffalo/pop with buffalo
Go
19
star
21

cli

The Buffalo CLI
Go
19
star
22

here

Go
16
star
23

buffalo-heroku

Sets up and deploys apps to Heroku
Go
16
star
24

events

Buffalo framework events management
Go
16
star
25

buffalo-plugins

This plugin has moved into github.com/gobuffalo/buffalo in buffalo v0.14.6. https://github.com/gobuffalo/buffalo
Go
16
star
26

gocraft-work-adapter

Implements the github.com/gobuffalo/buffalo/worker.Worker interface using the github.com/gocraft/work package.
Go
14
star
27

httptest

Go
14
star
28

mw-tokenauth

Buffalo token-based-authentication middleware
Go
13
star
29

buffalo-goth

Goth Generator for Buffalo
Go
12
star
30

toolkit

A tool discovery service for https://gobuffalo.io
Go
12
star
31

clara

Go
11
star
32

makr

File generation system
Go
11
star
33

packd

gobuffalo/packr interfaces
Go
9
star
34

buffalo-cli

Tools for developing Buffalo applications (v2 - WIP)
Go
9
star
35

logger

A common logging interface for the Buffalo ecosystem
Go
9
star
36

gothrecipe

A recipe for using Buffalo & Goth
Go
8
star
37

helpers

Go
8
star
38

release

Buffalo ecosystem release tool
Go
8
star
39

grift

Go based task runner
Go
8
star
40

mw-csrf

Buffalo CSRF Middleware
Go
7
star
41

mw-basicauth

Buffalo Basic Auth Middleware
Go
6
star
42

mw-i18n

Buffalo i18n Middleware
Go
6
star
43

homebrew-tap

Homebrew Formula for the buffalo projects binaries
Ruby
6
star
44

licenser

Go
5
star
45

meta

Introspection for buffalo applications
Go
5
star
46

buffalo-docker

This plugin has moved into github.com/gobuffalo/buffalo in buffalo v0.14.7.
Go
4
star
47

simple-ajax-recipe

A simple AJAX recipe for Buffalo
Go
4
star
48

soda

Soda is a CLI for https://github.com/gobuffalo/pop
Go
4
star
49

mw-forcessl

Buffalo Middleware to force SSL
Go
4
star
50

plugins

Go
4
star
51

mw-paramlogger

Buffalo Params Logger Middleware
Go
3
star
52

x

Collection of packages meant to be a "testing" ground for Buffalo packages
Go
3
star
53

mw-contenttype

Buffalo Content Type Middleware
Go
3
star
54

attrs

Go
2
star
55

plushgen

Go
2
star
56

pop-vgo

Shell
2
star
57

gogen

Go
1
star
58

replo

A GO REPL
Go
1
star
59

middleware

The default middleware for Buffalo apps
Go
1
star
60

mapgen

Go
1
star
61

mapi

Go
1
star
62

depgen

Go
1
star
63

gitgen

Makefile
1
star
64

syncx

Go
1
star