Fix asset provisioning to strip embedded share/radiantwave root
This commit is contained in:
@@ -150,7 +150,7 @@ func Run(bundled fs.FS) {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if err := assets.Provision(bundled, config.AssetsDir); err != nil {
|
||||
if err := assets.ProvisionAssets(bundled, config.AssetsDir); err != nil {
|
||||
logger.Error("failed to provision bundled assets into %s: %v", config.AssetsDir, err)
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,25 @@ import (
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
// embeddedRoot is the directory in the source tree (and therefore in the
|
||||
// embedded FS) where the bundled assets live. It mirrors the nix store
|
||||
// layout, but consumers expect the assets directly under the assets dir,
|
||||
// so this root is stripped during provisioning.
|
||||
const embeddedRoot = "share/radiantwave"
|
||||
|
||||
// ProvisionAssets provisions the bundled static assets (fonts, shaders, and
|
||||
// terms-of-service pages) into destDir, stripping the embedded
|
||||
// share/radiantwave root so the files land directly in destDir rather than
|
||||
// in a nested share/radiantwave/ subdirectory. Existing files are
|
||||
// overwritten so the deployed assets always match the running binary.
|
||||
func ProvisionAssets(bundled fs.FS, destDir string) error {
|
||||
root, err := fs.Sub(bundled, embeddedRoot)
|
||||
if err != nil {
|
||||
return fmt.Errorf("bundled assets missing %s root: %w", embeddedRoot, err)
|
||||
}
|
||||
return Provision(root, destDir)
|
||||
}
|
||||
|
||||
// Provision copies every file from the embedded filesystem into destDir,
|
||||
// preserving the relative directory structure. Existing files are
|
||||
// overwritten so the deployed assets always match the running binary.
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
"testing/fstest"
|
||||
)
|
||||
|
||||
//go:embed testdata
|
||||
@@ -38,6 +39,40 @@ func TestProvisionCopiesBundledFiles(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestProvisionAssetsStripsEmbeddedRoot is a regression test: provisioning
|
||||
// used to preserve the embedded share/radiantwave root, so assets landed in
|
||||
// <dataDir>/share/radiantwave/fonts instead of <dataDir>/fonts. ProvisionAssets
|
||||
// strips that root so consumers find the assets directly under the assets dir.
|
||||
func TestProvisionAssetsStripsEmbeddedRoot(t *testing.T) {
|
||||
fsys := fstest.MapFS{
|
||||
"share/radiantwave/fonts/TestFont.ttf": &fstest.MapFile{Data: []byte("font")},
|
||||
"share/radiantwave/shaders/text.frag": &fstest.MapFile{Data: []byte("frag")},
|
||||
"share/radiantwave/shaders/text.vert": &fstest.MapFile{Data: []byte("vert")},
|
||||
"share/radiantwave/tos/01 - WELCOME.html": &fstest.MapFile{Data: []byte("welcome")},
|
||||
}
|
||||
dest := t.TempDir()
|
||||
|
||||
if err := ProvisionAssets(fsys, dest); err != nil {
|
||||
t.Fatalf("ProvisionAssets returned error: %v", err)
|
||||
}
|
||||
|
||||
// Assets must land directly under dest, not under dest/share/radiantwave.
|
||||
for _, rel := range []string{
|
||||
"fonts/TestFont.ttf",
|
||||
"shaders/text.frag",
|
||||
"shaders/text.vert",
|
||||
"tos/01 - WELCOME.html",
|
||||
} {
|
||||
if _, err := os.Stat(filepath.Join(dest, filepath.FromSlash(rel))); err != nil {
|
||||
t.Errorf("expected %s to be provisioned directly under dest: %v", rel, err)
|
||||
}
|
||||
}
|
||||
|
||||
if _, err := os.Stat(filepath.Join(dest, "share")); !os.IsNotExist(err) {
|
||||
t.Errorf("unexpected share/ directory created under dest: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestProvisionOverwritesStaleFiles(t *testing.T) {
|
||||
dest := t.TempDir()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user