Vault is a simple tool to embed resource and asset files into a go binary. It generates go source files containing encoded and compressed resource files. The generated source code provides an api to retrieve the embedded resources without any additional dependencies and therefore the vault package is only needed to generate those source files.
go 1.9.7+
Install tool with go get
:
go get -u github.com/go-sharp/vault/vault-cli
Assuming a project folder like this:
webapp
|- dist
| |- js
| | |- app.js
| | '- moment.js
| |- css
| | '- app.css
| |- index.html
| '- bg.jpeg
|- handlers.go
|- models.go
'- main.go
#vault-cli [options] source destination
vault-cli ./dist ./res
This command will generate source files containing index.html
and bg.jpeg
as resources. Now the project folder looks like this:
webapp
|- dist
| |- js
| | |- app.js
| | '- moment.js
| |- css
| | '- app.css
| |- index.html
| '- bg.jpeg
|- res
| |- debug_dist_vault.go
| |- release_dist_vault.go
| '- shared_dist_vault.go
|- handlers.go
|- models.go
'- main.go
To include files in subdirectories use the -s
flag.
Use the -i
and -e
flags to include or exclude files. Both flags expecting a regular expression as input (see regexp) and can be specified multiple times.
vault-cli -s -i "[.]js$" -i "[.]html$" ./dist ./res
This will include only app.js
, moment.js
and index.html
.
vault-cli -s -e "app.js$" - ./dist ./res
This will include all files except app.js
. It is also possible to use both flags, so one could define a more general include pattern and then exclude some specific files. For example:
vault-cli -s -i "[.]js$" -e "test[.]js$" - ./dist ./res
This will include all javascript files but exclude test files.
Per default all included files will be compressed. If required, compression can be disabled with the -no-comp
flag.
The most straight forward way to invoke the vault-cli is to use the go:generate
directive in the main.go
file.
//go:generate vault-cli -s ./dist ./res
Then invoke the go generate
command to generate the resource files.
Create and use the asset loader in your program as shown below:
package main
import (
"fmt"
"log"
"github.com/example/webapp/res"
)
func main() {
// Create a loader (default: New{source folder name}Loader() -> can be changed with ResourceNameOption)
loader := res.NewDistLoader()
f, err := loader.Open("/bg.jpg")
if err != nil {
log.Fatalln(err)
}
// Check for error omitted, but you definitely should check for errors.
defer f.Close()
// Read content
data, err := ioutil.ReadAll(f)
if err != nil {
log.Fatalln(err)
}
// Write content to a file
if err := ioutil.WriteFile("bg.jpg", data, 0755); err != nil {
log.Fatalln(err)
}
f2, err := loader.Open("/js/app.js")
if err != nil {
log.Fatalln(err)
}
// Check for error omitted, but you definitely should check for errors.
defer f2.Close()
// Read content
data, err = ioutil.ReadAll(f2)
if err != nil {
log.Fatalln(err)
}
// Write to console
fmt.Println(data)
}
AssetLoader uses the relative path to the file within the source directory to lookup the file in the vault. The loader uses slashes /
as path separator on all platforms (macOS, Linux and Windows).
The asset loader implements only one method:
// AssetLoader implements a function to load an asset from the vault
type AssetLoader interface {
// Open loads a file from the vault.
Open(name string) (File, error)
}
Load returns a file instance with the following interface (see http.File) or an error:
// File is the interface definition in the http package.
type File interface {
io.Closer
io.Reader
io.Seeker
Readdir(count int) ([]os.FileInfo, error)
Stat() (os.FileInfo, error)
}
The asset loader implements the http.FileSystem
interface and can be used with the http.FileServer
handler. Just pass the loader to the FileServer function as follows:
http.Handle("/", http.FileServer(res.NewDistLoader()))
Run or build a program with go run -tags debug main.go
to enable the development mode. In development mode the loader bypasses the embedded files and reads directly from the source directory. Therefore it is important to run the program in the same folder as the vault-cli tool was invoked. Otherwise invoke vault-cli with the flag -rp
and specify the relative path to the source directory from the directory where the program will be executed. For example (folder structure as above):
# WorkingDir WebApp/dist
$~/workspace/src/webapp/dist> vault-cli -s -rp "./dist" ./ ../res
# WorkingDir WebApp
$~/workspace/src/webapp> go run -tags debug main.go
See Example folder
This software is licensed under the MIT License.