Go 1.16 embed instead of go-bindata

* Migrate off go-bindata to embed built-in fonts, levels and doodads in
  favor of Go 1.16 native embed functionality.
* `make bindata` prints a deprecation warning to not break older build
  scripts
* Removes all references of bindata from the program
This commit is contained in:
Noah 2021-07-13 18:02:57 -07:00
parent 26b1ac88dd
commit 3486050702
14 changed files with 109 additions and 58 deletions

View File

@ -46,8 +46,6 @@ $ python3 bootstrap.py
The bootstrap script will take care of the rest: The bootstrap script will take care of the rest:
* `apt install` all the dependencies (golang, SDL2, etc.) * `apt install` all the dependencies (golang, SDL2, etc.)
* Install the `go-bindata` command, needed to bundle assets like doodads
and fonts into the program.
* `git clone` various other repositories into a "deps/" folder in doodle's * `git clone` various other repositories into a "deps/" folder in doodle's
directory. These are things like my Go render library `go/render` and directory. These are things like my Go render library `go/render` and
`go/ui` as well as the doodle-rtp runtime package (sound effects, etc.) `go/ui` as well as the doodle-rtp runtime package (sound effects, etc.)
@ -100,16 +98,8 @@ cp ../masters/levels assets/levels
cp ../vendor/fonts assets/fonts cp ../vendor/fonts assets/fonts
mkdir rtp && cp -r ../rtp/* rtp/ mkdir rtp && cp -r ../rtp/* rtp/
# Ensure you have bindata CLI command. NOTE: below repo is # From the doodle repo:
# my fork of go-bindata, can find it elsewhere instead. make setup # -or-
# Future Go 1.16 will have native support to embed files and
# go-bindata will be not needed.
go get -u git.kirsle.net/go/bindata/...
# From the doodle repo: `make bindata-dev` will populate dummy .go
# files for bindata and allow the app to actually BUILD, otherwise the
# `go get` would fail.
make bindata-dev
go get ./... # install dependencies etc. go get ./... # install dependencies etc.
# The app should build now. Build and install the doodad tool. # The app should build now. Build and install the doodad tool.
@ -123,7 +113,12 @@ doodad --version
make dist make dist
# Build a cross-compiled Windows target from Linux. # Build a cross-compiled Windows target from Linux.
# (you'd run before `make dist` to make an uber release)
make mingw make mingw
# After make dist, `make release` will carve up Linux
# and Windows (mingw) builds and zip them up nicely.
make release
``` ```
The `make setup` command tries to do the above. The `make setup` command tries to do the above.
@ -132,7 +127,7 @@ The `make setup` command tries to do the above.
will build an app for distribution in the dist/ folder. will build an app for distribution in the dist/ folder.
Levels should be copied in from the doodle-masters repo into the Levels should be copied in from the doodle-masters repo into the
assets/levels/ folder before running `make bindata` to release the game. assets/levels/ folder before building the game.
## Fonts ## Fonts
@ -159,11 +154,8 @@ Makefile commands for Unix-likes:
* `make setup`: install Go dependencies and set up the build environment * `make setup`: install Go dependencies and set up the build environment
* `make doodads`: build the default Doodads from sources in `dev-assets/` * `make doodads`: build the default Doodads from sources in `dev-assets/`
* `make bindata`: embed the default doodads, levels and other assets into the
Go program. `make bindata-dev` for lightweight dev versions that will read
from the filesystem at runtime instead.
* `make build`: build the Doodle and Doodad binaries to the `bin/` folder. * `make build`: build the Doodle and Doodad binaries to the `bin/` folder.
* `make buildall`: runs all build steps: doodads, bindata, build. * `make buildall`: runs all build steps: doodads, build.
* `make build-free`: build the shareware binaries to the `bin/` folder. See * `make build-free`: build the shareware binaries to the `bin/` folder. See
Build Tags below. Build Tags below.
* `make build-debug`: build a debug binary (not release-mode) to the `bin/` * `make build-debug`: build a debug binary (not release-mode) to the `bin/`

View File

@ -12,7 +12,6 @@ LDFLAGS_W := -ldflags "-X main.Build=$(BUILD) -X main.BuildDate=$(BUILD_DATE) -H
# `make setup` to set up a new environment, pull dependencies, etc. # `make setup` to set up a new environment, pull dependencies, etc.
.PHONY: setup .PHONY: setup
setup: clean setup: clean
go get -u git.kirsle.net/go/bindata/...
go get ./... go get ./...
# `make build` to build the binary. # `make build` to build the binary.
@ -21,9 +20,9 @@ build:
go build $(LDFLAGS) -i -o bin/sketchymaze cmd/doodle/main.go go build $(LDFLAGS) -i -o bin/sketchymaze cmd/doodle/main.go
go build $(LDFLAGS) -i -o bin/doodad cmd/doodad/main.go go build $(LDFLAGS) -i -o bin/doodad cmd/doodad/main.go
# `make buildall` to run all build steps including doodads and bindata. # `make buildall` to run all build steps including doodads.
.PHONY: buildall .PHONY: buildall
buildall: doodads bindata build buildall: doodads build
# `make build-free` to build the binary in free mode. # `make build-free` to build the binary in free mode.
.PHONY: build-free .PHONY: build-free
@ -42,12 +41,12 @@ build-debug:
# `make bindata` generates the embedded binary assets package. # `make bindata` generates the embedded binary assets package.
.PHONY: bindata .PHONY: bindata
bindata: bindata:
go-bindata -pkg bindata -o pkg/bindata/bindata.go assets/... echo "make bindata: deprecated in favor of Go 1.16 embed; nothing was done"
# `make bindata-dev` generates the debug version of bindata package. # `make bindata-dev` generates the debug version of bindata package.
.PHONY: bindata-dev .PHONY: bindata-dev
bindata-dev: bindata-dev:
go-bindata -debug -pkg bindata -o pkg/bindata/bindata.go assets/... echo "make bindata-dev: deprecated in favor of Go 1.16 embed; nothing was done"
# `make wasm` builds the WebAssembly port. # `make wasm` builds the WebAssembly port.
.PHONY: wasm .PHONY: wasm
@ -72,7 +71,7 @@ doodads:
# `make mingw` to cross-compile a Windows binary with mingw. # `make mingw` to cross-compile a Windows binary with mingw.
.PHONY: mingw .PHONY: mingw
mingw: doodads bindata mingw: doodads
env CGO_ENABLED="1" CC="/usr/bin/x86_64-w64-mingw32-gcc" \ env CGO_ENABLED="1" CC="/usr/bin/x86_64-w64-mingw32-gcc" \
GOOS="windows" CGO_LDFLAGS="-lmingw32 -lSDL2" CGO_CFLAGS="-D_REENTRANT" \ GOOS="windows" CGO_LDFLAGS="-lmingw32 -lSDL2" CGO_CFLAGS="-D_REENTRANT" \
go build $(LDFLAGS_W) -i -o bin/sketchymaze.exe cmd/doodle/main.go go build $(LDFLAGS_W) -i -o bin/sketchymaze.exe cmd/doodle/main.go
@ -82,7 +81,7 @@ mingw: doodads bindata
# `make mingw-free` for Windows binary in free mode. # `make mingw-free` for Windows binary in free mode.
.PHONY: mingw-free .PHONY: mingw-free
mingw-free: doodads bindata mingw-free: doodads
env CGO_ENABLED="1" CC="/usr/bin/x86_64-w64-mingw32-gcc" \ env CGO_ENABLED="1" CC="/usr/bin/x86_64-w64-mingw32-gcc" \
GOOS="windows" CGO_LDFLAGS="-lmingw32 -lSDL2" CGO_CFLAGS="-D_REENTRANT" \ GOOS="windows" CGO_LDFLAGS="-lmingw32 -lSDL2" CGO_CFLAGS="-D_REENTRANT" \
go build $(LDFLAGS_W) -tags="shareware" -i -o bin/sketchymaze.exe cmd/doodle/main.go go build $(LDFLAGS_W) -tags="shareware" -i -o bin/sketchymaze.exe cmd/doodle/main.go
@ -99,11 +98,11 @@ release:
# `make mingw-release` runs a FULL end-to-end release of Linux and Windows # `make mingw-release` runs a FULL end-to-end release of Linux and Windows
# binaries of the game, zipped and tagged and ready to go. # binaries of the game, zipped and tagged and ready to go.
.PHONY: mingw-release .PHONY: mingw-release
mingw-release: doodads bindata build mingw __dist-common release mingw-release: doodads build mingw __dist-common release
# `make osx` to cross-compile a Mac OS binary with osxcross. # `make osx` to cross-compile a Mac OS binary with osxcross.
# .PHONY: osx # .PHONY: osx
# osx: doodads bindata # osx: doodads
# CGO_ENABLED=1 CC=[path-to-osxcross]/target/bin/[arch]-apple-darwin[version]-clang GOOS=darwin GOARCH=[arch] go build -tags static -ldflags "-s -w" -a # CGO_ENABLED=1 CC=[path-to-osxcross]/target/bin/[arch]-apple-darwin[version]-clang GOOS=darwin GOARCH=[arch] go build -tags static -ldflags "-s -w" -a
@ -124,11 +123,11 @@ test:
# `make dist` builds and tars up a release. # `make dist` builds and tars up a release.
.PHONY: dist .PHONY: dist
dist: doodads bindata build __dist-common dist: doodads build __dist-common
# `make dist-free` builds and tars up a release in shareware mode. # `make dist-free` builds and tars up a release in shareware mode.
.PHONY: dist-free .PHONY: dist-free
dist-free: doodads bindata build-free __dist-common dist-free: doodads build-free __dist-common
# Common logic behind `make dist` # Common logic behind `make dist`
.PHONY: __dist-common .PHONY: __dist-common

61
assets/assets_embed.go Normal file
View File

@ -0,0 +1,61 @@
// Package assets gets us off go-bindata by using Go 1.16 embed support.
//
// For Go 1.16 embed, this source file had to live inside the assets/ folder
// to embed the sub-files, so couldn't be under pkg/ like pkg/bindata/ was.
//
// Historically code referred to assets like "assets/fonts/DejaVuSans.ttf"
// but Go embed would just use "fonts/DejaVuSans.ttf" as that's what's relative
// to this source file.
//
// The functions in this module provide backwards compatibility by ignoring
// the "assets/" prefix sent by calling code.
package assets
import (
"embed"
"io/fs"
"strings"
)
//go:embed *
var Embedded embed.FS
// AssetDir returns the list of embedded files at the directory name.
func AssetDir(name string) ([]string, error) {
var result []string
name = strings.TrimPrefix(name, "assets/")
files, err := Embedded.ReadDir(name)
if err != nil {
return result, err
}
for _, file := range files {
if file.IsDir() {
continue
}
result = append(result, file.Name())
}
return result, nil
}
// Asset returns the byte data of an embedded asset.
func Asset(name string) ([]byte, error) {
return Embedded.ReadFile(strings.TrimPrefix(name, "assets/"))
}
// AssetNames dumps the names of all embedded assets,
// with their legacy "assets/" prefix from go-bindata.
func AssetNames() []string {
var result []string
fs.WalkDir(Embedded, ".", func(path string, d fs.DirEntry, err error) error {
if d != nil && !d.IsDir() {
result = append(result, "assets/"+path)
}
return nil
})
return result
}

View File

@ -11,9 +11,9 @@ import (
"strconv" "strconv"
"time" "time"
"git.kirsle.net/apps/doodle/assets"
doodle "git.kirsle.net/apps/doodle/pkg" doodle "git.kirsle.net/apps/doodle/pkg"
"git.kirsle.net/apps/doodle/pkg/balance" "git.kirsle.net/apps/doodle/pkg/balance"
"git.kirsle.net/apps/doodle/pkg/bindata"
"git.kirsle.net/apps/doodle/pkg/branding" "git.kirsle.net/apps/doodle/pkg/branding"
"git.kirsle.net/apps/doodle/pkg/license" "git.kirsle.net/apps/doodle/pkg/license"
"git.kirsle.net/apps/doodle/pkg/log" "git.kirsle.net/apps/doodle/pkg/log"
@ -142,9 +142,9 @@ func main() {
) )
// Load the SDL fonts in from bindata storage. // Load the SDL fonts in from bindata storage.
if fonts, err := bindata.AssetDir("assets/fonts"); err == nil { if fonts, err := assets.AssetDir("assets/fonts"); err == nil {
for _, file := range fonts { for _, file := range fonts {
data, err := bindata.Asset("assets/fonts/" + file) data, err := assets.Asset("assets/fonts/" + file)
if err != nil { if err != nil {
panic(err) panic(err)
} }

8
go.mod
View File

@ -1,6 +1,6 @@
module git.kirsle.net/apps/doodle module git.kirsle.net/apps/doodle
go 1.15 go 1.16
require ( require (
git.kirsle.net/go/audio v0.0.0-20200429055451-ae3b0695ba6f git.kirsle.net/go/audio v0.0.0-20200429055451-ae3b0695ba6f
@ -30,8 +30,8 @@ require (
// replace git.kirsle.net/go/audio => /home/kirsle/SketchyMaze/deps/audio // replace git.kirsle.net/go/audio => /home/kirsle/SketchyMaze/deps/audio
// replace git.kirsle.net/go/render => /run/build/doodle/deps/render // replace git.kirsle.net/go/render => /run/build/sketchymaze/deps/render
// replace git.kirsle.net/go/ui => /run/build/doodle/deps/ui // replace git.kirsle.net/go/ui => /run/build/sketchymaze/deps/ui
// replace git.kirsle.net/go/audio => /run/build/doodle/deps/audio // replace git.kirsle.net/go/audio => /run/build/sketchymaze/deps/audio

View File

@ -1 +0,0 @@
package bindata

View File

@ -7,7 +7,7 @@ import (
"runtime" "runtime"
"sort" "sort"
"git.kirsle.net/apps/doodle/pkg/bindata" "git.kirsle.net/apps/doodle/assets"
"git.kirsle.net/apps/doodle/pkg/filesystem" "git.kirsle.net/apps/doodle/pkg/filesystem"
"git.kirsle.net/apps/doodle/pkg/userdir" "git.kirsle.net/apps/doodle/pkg/userdir"
) )
@ -22,7 +22,7 @@ func List() ([]string, error) {
var names []string var names []string
// List built-in bindata campaigns. // List built-in bindata campaigns.
if files, err := bindata.AssetDir("assets/campaigns"); err == nil { if files, err := assets.AssetDir("assets/campaigns"); err == nil {
names = append(names, files...) names = append(names, files...)
} }

View File

@ -8,8 +8,8 @@ import (
"strconv" "strconv"
"strings" "strings"
"git.kirsle.net/apps/doodle/assets"
"git.kirsle.net/apps/doodle/pkg/balance" "git.kirsle.net/apps/doodle/pkg/balance"
"git.kirsle.net/apps/doodle/pkg/bindata"
"git.kirsle.net/apps/doodle/pkg/enum" "git.kirsle.net/apps/doodle/pkg/enum"
"git.kirsle.net/apps/doodle/pkg/log" "git.kirsle.net/apps/doodle/pkg/log"
"git.kirsle.net/apps/doodle/pkg/modal" "git.kirsle.net/apps/doodle/pkg/modal"
@ -114,11 +114,11 @@ func (c Command) ExtractBindata(d *Doodle, path string) error {
return err return err
} }
for _, filename := range bindata.AssetNames() { for _, filename := range assets.AssetNames() {
outfile := filepath.Join(path, filename) outfile := filepath.Join(path, filename)
log.Info("Extracting bindata: %s to: %s", filename, outfile) log.Info("Extracting bindata: %s to: %s", filename, outfile)
data, err := bindata.Asset(filename) data, err := assets.Asset(filename)
if err != nil { if err != nil {
d.Flash("error on file %s: %s", filename, err) d.Flash("error on file %s: %s", filename, err)
continue continue

View File

@ -8,7 +8,7 @@ import (
"runtime" "runtime"
"strings" "strings"
"git.kirsle.net/apps/doodle/pkg/bindata" "git.kirsle.net/apps/doodle/assets"
"git.kirsle.net/apps/doodle/pkg/log" "git.kirsle.net/apps/doodle/pkg/log"
"git.kirsle.net/apps/doodle/pkg/userdir" "git.kirsle.net/apps/doodle/pkg/userdir"
) )
@ -38,7 +38,7 @@ func (d *Doodle) EditFile(filename string) error {
extension := strings.ToLower(filepath.Ext(filename)) extension := strings.ToLower(filepath.Ext(filename))
// Check the system level storage. TODO: no editing of system levels // Check the system level storage. TODO: no editing of system levels
if _, err := bindata.Asset("assets/levels/" + filename); err == nil { if _, err := assets.Asset("assets/levels/" + filename); err == nil {
log.Info("Found level %s in bindata", filename) log.Info("Found level %s in bindata", filename)
return d.EditDrawing(filename) return d.EditDrawing(filename)
} }

View File

@ -8,8 +8,8 @@ import (
"sort" "sort"
"strings" "strings"
"git.kirsle.net/apps/doodle/assets"
"git.kirsle.net/apps/doodle/pkg/balance" "git.kirsle.net/apps/doodle/pkg/balance"
"git.kirsle.net/apps/doodle/pkg/bindata"
"git.kirsle.net/apps/doodle/pkg/branding" "git.kirsle.net/apps/doodle/pkg/branding"
"git.kirsle.net/apps/doodle/pkg/enum" "git.kirsle.net/apps/doodle/pkg/enum"
"git.kirsle.net/apps/doodle/pkg/filesystem" "git.kirsle.net/apps/doodle/pkg/filesystem"
@ -30,7 +30,7 @@ func ListDoodads() ([]string, error) {
var names []string var names []string
// List doodads embedded into the binary. // List doodads embedded into the binary.
if files, err := bindata.AssetDir("assets/doodads"); err == nil { if files, err := assets.AssetDir("assets/doodads"); err == nil {
names = append(names, files...) names = append(names, files...)
} }
@ -77,7 +77,7 @@ func ListBuiltin() ([]string, error) {
var names []string var names []string
// List doodads embedded into the binary. // List doodads embedded into the binary.
if files, err := bindata.AssetDir("assets/doodads"); err == nil { if files, err := assets.AssetDir("assets/doodads"); err == nil {
names = append(names, files...) names = append(names, files...)
} }
@ -143,7 +143,7 @@ func LoadFile(filename string) (*Doodad, error) {
} }
// Do we have the file in bindata? // Do we have the file in bindata?
if jsonData, err := bindata.Asset(filename); err == nil { if jsonData, err := assets.Asset(filename); err == nil {
return FromJSON(filename, jsonData) return FromJSON(filename, jsonData)
} }

View File

@ -9,7 +9,7 @@ import (
"runtime" "runtime"
"strings" "strings"
"git.kirsle.net/apps/doodle/pkg/bindata" "git.kirsle.net/apps/doodle/assets"
"git.kirsle.net/apps/doodle/pkg/enum" "git.kirsle.net/apps/doodle/pkg/enum"
"git.kirsle.net/apps/doodle/pkg/userdir" "git.kirsle.net/apps/doodle/pkg/userdir"
) )
@ -105,7 +105,7 @@ func FindFile(filename string) (string, error) {
candidate := filepath.Join(SystemLevelsPath, filename) candidate := filepath.Join(SystemLevelsPath, filename)
// embedded system doodad? // embedded system doodad?
if _, err := bindata.Asset(candidate); err == nil { if _, err := assets.Asset(candidate); err == nil {
return candidate, nil return candidate, nil
} }
@ -133,7 +133,7 @@ func FindFile(filename string) (string, error) {
candidate := filepath.Join(SystemDoodadsPath, filename) candidate := filepath.Join(SystemDoodadsPath, filename)
// embedded system doodad? // embedded system doodad?
if _, err := bindata.Asset(candidate); err == nil { if _, err := assets.Asset(candidate); err == nil {
return candidate, nil return candidate, nil
} }

View File

@ -7,7 +7,7 @@ import (
"runtime" "runtime"
"strings" "strings"
"git.kirsle.net/apps/doodle/pkg/bindata" "git.kirsle.net/apps/doodle/assets"
"git.kirsle.net/apps/doodle/pkg/branding" "git.kirsle.net/apps/doodle/pkg/branding"
"git.kirsle.net/apps/doodle/pkg/enum" "git.kirsle.net/apps/doodle/pkg/enum"
"git.kirsle.net/apps/doodle/pkg/filesystem" "git.kirsle.net/apps/doodle/pkg/filesystem"
@ -21,7 +21,7 @@ func ListSystemLevels() ([]string, error) {
var names = []string{} var names = []string{}
// Add the levels embedded inside the binary. // Add the levels embedded inside the binary.
if levels, err := bindata.AssetDir("assets/levels"); err == nil { if levels, err := assets.AssetDir("assets/levels"); err == nil {
names = append(names, levels...) names = append(names, levels...)
} }
@ -56,7 +56,7 @@ func LoadFile(filename string) (*Level, error) {
} }
// Do we have the file in bindata? // Do we have the file in bindata?
if jsonData, err := bindata.Asset(filename); err == nil { if jsonData, err := assets.Asset(filename); err == nil {
log.Debug("Level %s: loaded from embedded bindata", filename) log.Debug("Level %s: loaded from embedded bindata", filename)
return FromJSON(filename, jsonData) return FromJSON(filename, jsonData)
} }

View File

@ -8,7 +8,7 @@ import (
"os" "os"
"runtime" "runtime"
"git.kirsle.net/apps/doodle/pkg/bindata" "git.kirsle.net/apps/doodle/assets"
"git.kirsle.net/apps/doodle/pkg/log" "git.kirsle.net/apps/doodle/pkg/log"
"git.kirsle.net/apps/doodle/pkg/wasm" "git.kirsle.net/apps/doodle/pkg/wasm"
"git.kirsle.net/go/render" "git.kirsle.net/go/render"
@ -21,7 +21,7 @@ import (
// NOTE: only .png images supported as of now. TODO // NOTE: only .png images supported as of now. TODO
func LoadImage(e render.Engine, filename string) (*ui.Image, error) { func LoadImage(e render.Engine, filename string) (*ui.Image, error) {
// Try the bindata first. // Try the bindata first.
if data, err := bindata.Asset(filename); err == nil { if data, err := assets.Asset(filename); err == nil {
log.Debug("sprites.LoadImage: %s from bindata", filename) log.Debug("sprites.LoadImage: %s from bindata", filename)
img, err := png.Decode(bytes.NewBuffer(data)) img, err := png.Decode(bytes.NewBuffer(data))

View File

@ -2,15 +2,15 @@ package wallpaper
import ( import (
"bytes" "bytes"
"encoding/base64"
"image" "image"
"image/draw" "image/draw"
"os" "os"
"path/filepath" "path/filepath"
"runtime" "runtime"
"strings" "strings"
"encoding/base64"
"git.kirsle.net/apps/doodle/pkg/bindata" "git.kirsle.net/apps/doodle/assets"
"git.kirsle.net/apps/doodle/pkg/filesystem" "git.kirsle.net/apps/doodle/pkg/filesystem"
"git.kirsle.net/apps/doodle/pkg/log" "git.kirsle.net/apps/doodle/pkg/log"
"git.kirsle.net/go/render" "git.kirsle.net/go/render"
@ -84,7 +84,7 @@ func FromFile(e render.Engine, filename string, embeddable filesystem.Embeddable
log.Debug("wallpaper.FromFile(%s): found in embedded level files", filename) log.Debug("wallpaper.FromFile(%s): found in embedded level files", filename)
bin, _ := base64.StdEncoding.DecodeString(string(data)) bin, _ := base64.StdEncoding.DecodeString(string(data))
img, format, imgErr = image.Decode(bytes.NewReader(bin)) img, format, imgErr = image.Decode(bytes.NewReader(bin))
} else if data, err := bindata.Asset(filename); err == nil { } else if data, err := assets.Asset(filename); err == nil {
log.Debug("wallpaper.FromFile(%s): found in program bindata", filename) log.Debug("wallpaper.FromFile(%s): found in program bindata", filename)
fh := bytes.NewBuffer(data) fh := bytes.NewBuffer(data)
img, format, imgErr = image.Decode(fh) img, format, imgErr = image.Decode(fh)