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.
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 change with ResourceNameOption)
loader := res.NewDistLoader()
f, err := loader.Load("/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.Load("/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 {
// Load loads a file from the vault.
Load(name string) (File, error)
}
Load returns a file instance with the following interface or an error:
// File is the vault abstraction of a file.
type File interface {
io.ReadCloser
// Size returns the size of the file.
Size() int64
// Name returns the name of the file.
Name() string
// ModTime returns the modification time.
ModTime() time.Time
// Path is the registered path within the vault.
Path() string
}
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
This software is licensed under the MIT License.