Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Integralist/ef5eb39ec34f5b8734bd81958be3a5e1 to your computer and use it in GitHub Desktop.
Save Integralist/ef5eb39ec34f5b8734bd81958be3a5e1 to your computer and use it in GitHub Desktop.
[golang embed static file inside of compiled binary] #go #golang #embed #static
// Refer to https://tip.golang.org/pkg/embed/ for lots of examples
//
// Here are some embed patterns to try (these can be layered on top of each other with a single variable!):
//
// downloads/* -> embed.FS
// image/ css/ js/ -> embed.FS
// favicon.ico robots.txt index.html -> embed.FS
//
// When using `var f embed.FS` you can then utilise that type's methods:
//
// func (FS) Open
// func (FS) ReadDir
// func (FS) ReadFile
//
// FS implements fs.FS, so it can be used with any package that understands file system interfaces, including net/http, text/template, and html/template.
package main
import (
_ "embed"
"fmt"
)
//go:embed config.toml
var config string // []byte might be more flexible!
func main() {
fmt.Printf("%+v\n", config)
// You can also combine it with a static file server.
/*
http.Handle("/", http.FileServer(http.FS(static)))
log.Fatal(http.ListenAndServe(":8080", nil))
*/
}

Go version 1.16 introduced an embed package which made embedding static data very easy.

In prior versions you would need to run go generate with a script that searched for files based on a given pattern, read the file into memory and to generate a new .go file with the file data assigned to package level constants.

The below demonstrates this process.

.
├── README.md
├── golang.svg
├── images.go
├── main.go
└── scripts
    └── embed.go

Embed

package main

import (
	"io"
	"io/ioutil"
	"os"
	"strings"
)

// Reads all .svg files in the current folder
// and encodes them as strings literals in images.go
//
// NOTE: The images.go file will be within the `main` package namespace.
func main() {
	fs, _ := ioutil.ReadDir(".")
	out, _ := os.Create("images.go")
	out.Write([]byte("package main \n\nconst (\n"))
	for _, f := range fs {
		if strings.HasSuffix(f.Name(), ".svg") {
			out.Write([]byte(strings.TrimSuffix(f.Name(), ".svg") + " = `"))
			f, _ := os.Open(f.Name())
			io.Copy(out, f)
			out.Write([]byte("`\n"))
		}
	}
	out.Write([]byte(")\n"))
}

Main

NOTE: Run with go run . so that all main package files are picked up.

package main

import "fmt"

//go:generate go run scripts/embed.go

func main() {
	fmt.Print(golang)
}

SVG

<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
	 viewBox="0 0 254.5 225" style="enable-background:new 0 0 254.5 225;" xml:space="preserve">
<style type="text/css">
	.st0{fill:#2DBCAF;}
	.st1{fill:#5DC9E1;}
	.st2{fill:#FDDD00;}
	.st3{fill:#CE3262;}
	.st4{fill:#00ACD7;}
	.st5{fill:#FFFFFF;}
</style>
<g>
	<g>
		<g>
			<g>
				<path class="st4" d="M40.2,101.1c-0.4,0-0.5-0.2-0.3-0.5l2.1-2.7c0.2-0.3,0.7-0.5,1.1-0.5l35.7,0c0.4,0,0.5,0.3,0.3,0.6
					l-1.7,2.6c-0.2,0.3-0.7,0.6-1,0.6L40.2,101.1z"/>
			</g>
		</g>
	</g>
	<g>
		<g>
			<g>
				<path class="st4" d="M25.1,110.3c-0.4,0-0.5-0.2-0.3-0.5l2.1-2.7c0.2-0.3,0.7-0.5,1.1-0.5l45.6,0c0.4,0,0.6,0.3,0.5,0.6
					l-0.8,2.4c-0.1,0.4-0.5,0.6-0.9,0.6L25.1,110.3z"/>
			</g>
		</g>
	</g>
	<g>
		<g>
			<g>
				<path class="st4" d="M49.3,119.5c-0.4,0-0.5-0.3-0.3-0.6l1.4-2.5c0.2-0.3,0.6-0.6,1-0.6l20,0c0.4,0,0.6,0.3,0.6,0.7l-0.2,2.4
					c0,0.4-0.4,0.7-0.7,0.7L49.3,119.5z"/>
			</g>
		</g>
	</g>
	<g>
		<g id="CXHf1q_3_">
			<g>
				<g>
					<path class="st4" d="M153.1,99.3c-6.3,1.6-10.6,2.8-16.8,4.4c-1.5,0.4-1.6,0.5-2.9-1c-1.5-1.7-2.6-2.8-4.7-3.8
						c-6.3-3.1-12.4-2.2-18.1,1.5c-6.8,4.4-10.3,10.9-10.2,19c0.1,8,5.6,14.6,13.5,15.7c6.8,0.9,12.5-1.5,17-6.6
						c0.9-1.1,1.7-2.3,2.7-3.7c-3.6,0-8.1,0-19.3,0c-2.1,0-2.6-1.3-1.9-3c1.3-3.1,3.7-8.3,5.1-10.9c0.3-0.6,1-1.6,2.5-1.6
						c5.1,0,23.9,0,36.4,0c-0.2,2.7-0.2,5.4-0.6,8.1c-1.1,7.2-3.8,13.8-8.2,19.6c-7.2,9.5-16.6,15.4-28.5,17
						c-9.8,1.3-18.9-0.6-26.9-6.6c-7.4-5.6-11.6-13-12.7-22.2c-1.3-10.9,1.9-20.7,8.5-29.3c7.1-9.3,16.5-15.2,28-17.3
						c9.4-1.7,18.4-0.6,26.5,4.9c5.3,3.5,9.1,8.3,11.6,14.1C154.7,98.5,154.3,99,153.1,99.3z"/>
				</g>
				<g>
					<path class="st4" d="M186.2,154.6c-9.1-0.2-17.4-2.8-24.4-8.8c-5.9-5.1-9.6-11.6-10.8-19.3c-1.8-11.3,1.3-21.3,8.1-30.2
						c7.3-9.6,16.1-14.6,28-16.7c10.2-1.8,19.8-0.8,28.5,5.1c7.9,5.4,12.8,12.7,14.1,22.3c1.7,13.5-2.2,24.5-11.5,33.9
						c-6.6,6.7-14.7,10.9-24,12.8C191.5,154.2,188.8,154.3,186.2,154.6z M210,114.2c-0.1-1.3-0.1-2.3-0.3-3.3
						c-1.8-9.9-10.9-15.5-20.4-13.3c-9.3,2.1-15.3,8-17.5,17.4c-1.8,7.8,2,15.7,9.2,18.9c5.5,2.4,11,2.1,16.3-0.6
						C205.2,129.2,209.5,122.8,210,114.2z"/>
				</g>
			</g>
		</g>
	</g>
</g>
</svg>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment