From 348605070261896fbf51b0bdccd439cd2bff4564 Mon Sep 17 00:00:00 2001 From: Noah Petherbridge Date: Tue, 13 Jul 2021 18:02:57 -0700 Subject: [PATCH] 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 --- Building.md | 26 ++++++--------- Makefile | 21 ++++++------- assets/assets_embed.go | 61 ++++++++++++++++++++++++++++++++++++ cmd/doodle/main.go | 6 ++-- go.mod | 8 ++--- pkg/bindata/doc.go | 1 - pkg/campaign/files.go | 4 +-- pkg/commands.go | 6 ++-- pkg/config.go | 4 +-- pkg/doodads/fmt_readwrite.go | 8 ++--- pkg/filesystem/filesystem.go | 6 ++-- pkg/level/fmt_readwrite.go | 6 ++-- pkg/sprites/sprites.go | 4 +-- pkg/wallpaper/wallpaper.go | 6 ++-- 14 files changed, 109 insertions(+), 58 deletions(-) create mode 100644 assets/assets_embed.go delete mode 100644 pkg/bindata/doc.go diff --git a/Building.md b/Building.md index 4463546..7fdd556 100644 --- a/Building.md +++ b/Building.md @@ -46,8 +46,6 @@ $ python3 bootstrap.py The bootstrap script will take care of the rest: * `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 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.) @@ -100,16 +98,8 @@ cp ../masters/levels assets/levels cp ../vendor/fonts assets/fonts mkdir rtp && cp -r ../rtp/* rtp/ -# Ensure you have bindata CLI command. NOTE: below repo is -# my fork of go-bindata, can find it elsewhere instead. -# 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 +# From the doodle repo: +make setup # -or- go get ./... # install dependencies etc. # The app should build now. Build and install the doodad tool. @@ -123,7 +113,12 @@ doodad --version make dist # Build a cross-compiled Windows target from Linux. +# (you'd run before `make dist` to make an uber release) 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. @@ -132,7 +127,7 @@ The `make setup` command tries to do the above. will build an app for distribution in the dist/ folder. 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 @@ -159,11 +154,8 @@ Makefile commands for Unix-likes: * `make setup`: install Go dependencies and set up the build environment * `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 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 Build Tags below. * `make build-debug`: build a debug binary (not release-mode) to the `bin/` diff --git a/Makefile b/Makefile index 980cb63..17a603b 100644 --- a/Makefile +++ b/Makefile @@ -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. .PHONY: setup setup: clean - go get -u git.kirsle.net/go/bindata/... go get ./... # `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/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 -buildall: doodads bindata build +buildall: doodads build # `make build-free` to build the binary in free mode. .PHONY: build-free @@ -42,12 +41,12 @@ build-debug: # `make bindata` generates the embedded binary assets package. .PHONY: 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. .PHONY: 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. .PHONY: wasm @@ -72,7 +71,7 @@ doodads: # `make mingw` to cross-compile a Windows binary with mingw. .PHONY: mingw -mingw: doodads bindata +mingw: doodads env CGO_ENABLED="1" CC="/usr/bin/x86_64-w64-mingw32-gcc" \ GOOS="windows" CGO_LDFLAGS="-lmingw32 -lSDL2" CGO_CFLAGS="-D_REENTRANT" \ 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. .PHONY: mingw-free -mingw-free: doodads bindata +mingw-free: doodads env CGO_ENABLED="1" CC="/usr/bin/x86_64-w64-mingw32-gcc" \ 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 @@ -99,11 +98,11 @@ release: # `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. .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. # .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 @@ -124,11 +123,11 @@ test: # `make dist` builds and tars up a release. .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. .PHONY: dist-free -dist-free: doodads bindata build-free __dist-common +dist-free: doodads build-free __dist-common # Common logic behind `make dist` .PHONY: __dist-common diff --git a/assets/assets_embed.go b/assets/assets_embed.go new file mode 100644 index 0000000..5ebb319 --- /dev/null +++ b/assets/assets_embed.go @@ -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 +} diff --git a/cmd/doodle/main.go b/cmd/doodle/main.go index b342cb6..40bf9ff 100644 --- a/cmd/doodle/main.go +++ b/cmd/doodle/main.go @@ -11,9 +11,9 @@ import ( "strconv" "time" + "git.kirsle.net/apps/doodle/assets" doodle "git.kirsle.net/apps/doodle/pkg" "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/license" "git.kirsle.net/apps/doodle/pkg/log" @@ -142,9 +142,9 @@ func main() { ) // 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 { - data, err := bindata.Asset("assets/fonts/" + file) + data, err := assets.Asset("assets/fonts/" + file) if err != nil { panic(err) } diff --git a/go.mod b/go.mod index 4374146..5b63921 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module git.kirsle.net/apps/doodle -go 1.15 +go 1.16 require ( 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/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 diff --git a/pkg/bindata/doc.go b/pkg/bindata/doc.go deleted file mode 100644 index e9ec81d..0000000 --- a/pkg/bindata/doc.go +++ /dev/null @@ -1 +0,0 @@ -package bindata diff --git a/pkg/campaign/files.go b/pkg/campaign/files.go index 0e84a6c..40218ee 100644 --- a/pkg/campaign/files.go +++ b/pkg/campaign/files.go @@ -7,7 +7,7 @@ import ( "runtime" "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/userdir" ) @@ -22,7 +22,7 @@ func List() ([]string, error) { var names []string // 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...) } diff --git a/pkg/commands.go b/pkg/commands.go index da0470a..451d5d4 100644 --- a/pkg/commands.go +++ b/pkg/commands.go @@ -8,8 +8,8 @@ import ( "strconv" "strings" + "git.kirsle.net/apps/doodle/assets" "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/log" "git.kirsle.net/apps/doodle/pkg/modal" @@ -114,11 +114,11 @@ func (c Command) ExtractBindata(d *Doodle, path string) error { return err } - for _, filename := range bindata.AssetNames() { + for _, filename := range assets.AssetNames() { outfile := filepath.Join(path, filename) log.Info("Extracting bindata: %s to: %s", filename, outfile) - data, err := bindata.Asset(filename) + data, err := assets.Asset(filename) if err != nil { d.Flash("error on file %s: %s", filename, err) continue diff --git a/pkg/config.go b/pkg/config.go index 57bf52b..84874d9 100644 --- a/pkg/config.go +++ b/pkg/config.go @@ -8,7 +8,7 @@ import ( "runtime" "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/userdir" ) @@ -38,7 +38,7 @@ func (d *Doodle) EditFile(filename string) error { extension := strings.ToLower(filepath.Ext(filename)) // 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) return d.EditDrawing(filename) } diff --git a/pkg/doodads/fmt_readwrite.go b/pkg/doodads/fmt_readwrite.go index 7582278..db723bd 100644 --- a/pkg/doodads/fmt_readwrite.go +++ b/pkg/doodads/fmt_readwrite.go @@ -8,8 +8,8 @@ import ( "sort" "strings" + "git.kirsle.net/apps/doodle/assets" "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/enum" "git.kirsle.net/apps/doodle/pkg/filesystem" @@ -30,7 +30,7 @@ func ListDoodads() ([]string, error) { var names []string // 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...) } @@ -77,7 +77,7 @@ func ListBuiltin() ([]string, error) { var names []string // 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...) } @@ -143,7 +143,7 @@ func LoadFile(filename string) (*Doodad, error) { } // 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) } diff --git a/pkg/filesystem/filesystem.go b/pkg/filesystem/filesystem.go index 4c457cb..b1d16aa 100644 --- a/pkg/filesystem/filesystem.go +++ b/pkg/filesystem/filesystem.go @@ -9,7 +9,7 @@ import ( "runtime" "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/userdir" ) @@ -105,7 +105,7 @@ func FindFile(filename string) (string, error) { candidate := filepath.Join(SystemLevelsPath, filename) // embedded system doodad? - if _, err := bindata.Asset(candidate); err == nil { + if _, err := assets.Asset(candidate); err == nil { return candidate, nil } @@ -133,7 +133,7 @@ func FindFile(filename string) (string, error) { candidate := filepath.Join(SystemDoodadsPath, filename) // embedded system doodad? - if _, err := bindata.Asset(candidate); err == nil { + if _, err := assets.Asset(candidate); err == nil { return candidate, nil } diff --git a/pkg/level/fmt_readwrite.go b/pkg/level/fmt_readwrite.go index 52eb599..5d07850 100644 --- a/pkg/level/fmt_readwrite.go +++ b/pkg/level/fmt_readwrite.go @@ -7,7 +7,7 @@ import ( "runtime" "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/enum" "git.kirsle.net/apps/doodle/pkg/filesystem" @@ -21,7 +21,7 @@ func ListSystemLevels() ([]string, error) { var names = []string{} // 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...) } @@ -56,7 +56,7 @@ func LoadFile(filename string) (*Level, error) { } // 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) return FromJSON(filename, jsonData) } diff --git a/pkg/sprites/sprites.go b/pkg/sprites/sprites.go index cbf40b9..5ce9d66 100644 --- a/pkg/sprites/sprites.go +++ b/pkg/sprites/sprites.go @@ -8,7 +8,7 @@ import ( "os" "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/wasm" "git.kirsle.net/go/render" @@ -21,7 +21,7 @@ import ( // NOTE: only .png images supported as of now. TODO func LoadImage(e render.Engine, filename string) (*ui.Image, error) { // 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) img, err := png.Decode(bytes.NewBuffer(data)) diff --git a/pkg/wallpaper/wallpaper.go b/pkg/wallpaper/wallpaper.go index 2be13b2..e737be6 100644 --- a/pkg/wallpaper/wallpaper.go +++ b/pkg/wallpaper/wallpaper.go @@ -2,15 +2,15 @@ package wallpaper import ( "bytes" + "encoding/base64" "image" "image/draw" "os" "path/filepath" "runtime" "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/log" "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) bin, _ := base64.StdEncoding.DecodeString(string(data)) 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) fh := bytes.NewBuffer(data) img, format, imgErr = image.Decode(fh)