go.rice is a Go package that makes working with resources such as html,js,css,images and templates very easy. During development go.rice
will load required files directly from disk. Upon deployment it is easy to add all resource files to a executable using the rice
tool, without changing the source code for your package. go.rice provides several methods to add resources to a binary.
The first thing go.rice does is finding the correct absolute path for your resource files. Say you are executing go binary in your home directory, but your html-files
are located in $GOPATH/src/yourApplication/html-files
. go.rice
will lookup the correct path for that directory (relative to the location of yourApplication). The only thing you have to do is include the resources using rice.FindBox("html-files")
.
This only works when the source is available to the machine executing the binary. Which is always the case when the binary was installed with go get
or go install
. It might occur that you wish to simply provide a binary, without source. The rice
tool analyses source code and finds call's to rice.FindBox(..)
and adds the required directories to the executable binary. There are several methods to add these resources. You can 'embed' by generating go source code, or append the resource to the executable as zip file. In both cases go.rice
will detect the embedded or appended resources and load those, instead of looking up files from disk.
Use go get
for the package and go install
for the tool.
go get github.com/GeertJohan/go.rice
go get github.com/GeertJohan/go.rice/rice
Import the package: import "github.com/GeertJohan/go.rice"
Serving a static content folder over HTTP with a rice Box
http.Handle("/", http.FileServer(rice.MustFindBox("http-files").HTTPBox()))
http.ListenAndServe(":8080", nil)
Loading a template
// find a rice.Box
templateBox, err := rice.FindBox("example-templates")
if err != nil {
log.Fatal(err)
}
// get file contents as string
templateString, err := templateBox.String("message.tmpl")
if err != nil {
log.Fatal(err)
}
// parse and execute the template
tmplMessage, err := template.New("message").Parse(templateString)
if err != nil {
log.Fatal(err)
}
tmplMessage.Execute(os.Stdout, map[string]string{"Message": "Hello, world!"})
The rice
tool lets you add the resources to a binary executable so the files are not loaded from the filesystem anymore. This creates a 'standalone' executable. There are several ways to add the resources to a binary, each has pro's and con's but all will work without requiring changes to the way you load the resources.
Embed resources by generating Go source code
This method must be executed before building. It generates Go source files that are compiled by the go compiler into the binary.
The downside with this option is that the generated go source files can become very large, which will slow down compilation and require lots of memory to compile.
Execute the following commands:
rice embed
go build
Append resources to executable as zip file
Does not work on windows (yet)
This method changes an allready built executable. It appends the resources as zip file to the binary. It makes compilation a lot faster and can be used with large resource files.
Downsides for appending are that it requires zip
to be installed and does not provide a working Seek method.
Run the following commands to create a standalone executable.
go build -o example
rice append --exec example
Run rice -h
for information about all options.
You can run the -h option for each sub-command, e.g. rice append -h
.
When opening a new box, the rice package tries to locate the resources in the following order:
- embedded in generated go source
- appended as zip
- 'live' from filesystem
This project is licensed under a Simplified BSD license. Please read the LICENSE file.
This package is not completed yet. Though it already provides working embedding, some important featuers are still missing.
- implement Readdir() correctly on virtualDir
- automated testing with TravisCI or Drone important
- in-code TODO's
- find boxes in imported packages
Less important stuff:
- rice.FindSingle(..) that loads and embeds a single file as oposed to a complete directory. It should have methods .String(), .Bytes() and .File()
- The rice tool uses a simple regexp to find calls to
rice.FindBox(..)
, this should be changed togo/ast
or maybego.tools/oracle
? - idea, os/arch dependent embeds. rice checks if embedding file has _os_arch or build flags. If box is not requested by file without buildflags, then the buildflags are applied to the embed file.
You will find package documentation at godoc.org/github.com/GeertJohan/go.rice.