diff --git a/assets/fingerprint.go b/assets/fingerprint.go index a6e77c4..3f5a7f8 100644 --- a/assets/fingerprint.go +++ b/assets/fingerprint.go @@ -11,15 +11,16 @@ import ( // PathFor returns the fingerprinted path for a given // file. If the path passed contains the hash it will -// return the same path. +// return the same path only in GO_ENV=development // filename to open should be the file without the prefix // filename for the map should be the file without the prefix // filename returned should be the file with the prefix func (m *manager) PathFor(name string) (string, error) { normalized := m.normalize(name) - if hashed, ok := m.fileToHash[normalized]; ok { - return path.Join(m.servingPath, hashed), nil + + if hashed, ok := m.fileToHash[normalized]; ok && os.Getenv("GO_ENV") != "development" { + return path.Join("/", m.servingPath, hashed), nil } // Compute the hash of the file @@ -38,6 +39,12 @@ func (m *manager) PathFor(name string) (string, error) { m.fmut.Lock() defer m.fmut.Unlock() + + // Delete previous asset hash from map + if old, exists := m.fileToHash[normalized]; exists && old != filename { + delete(m.HashToFile, old) + } + m.fileToHash[normalized] = filename m.HashToFile[filename] = normalized diff --git a/assets/fingerprint_test.go b/assets/fingerprint_test.go index 357aa21..05e8903 100644 --- a/assets/fingerprint_test.go +++ b/assets/fingerprint_test.go @@ -9,7 +9,7 @@ import ( ) func TestFingerprint(t *testing.T) { - assetsPath := "/files/" + assetsPath := "/files" m := assets.NewManager(fstest.MapFS{ "main.js": {Data: []byte("AAA")}, "other/main.js": {Data: []byte("AAA")}, @@ -125,6 +125,45 @@ func TestFingerprint(t *testing.T) { } }) + t.Run("HandlerPattern", func(t *testing.T) { + cases := []struct { + pattern string + expected string + }{ + {"/", ""}, + {"/", ""}, + + {"files", "/files/"}, + {"/files/", "/files/"}, + {"files/", "/files/"}, + {"/files/", "/files/"}, + + {"files/path", "/files/path/"}, + {"/files/path", "/files/path/"}, + {"files/path/", "/files/path/"}, + {"/files/path/", "/files/path/"}, + } + + for _, c := range cases { + m := assets.NewManager(fstest.MapFS{}, c.pattern) + if m.HandlerPattern() != c.expected { + t.Errorf("Expected %q to equal %q", m.HandlerPattern(), c.expected) + } + } + }) + + t.Run("HandlerPattern with root serving path", func(t *testing.T) { + m := assets.NewManager(fstest.MapFS{}, "/") + if m.HandlerPattern() == "/" { + t.Errorf("Expected empty string, got %s", m.HandlerPattern()) + } + + m = assets.NewManager(fstest.MapFS{}, "public") + if m.HandlerPattern() != "/public/" { + t.Errorf("Expected '/public/', got %s", m.HandlerPattern()) + } + }) + t.Run("PathFor normalize file path", func(t *testing.T) { cases := []struct { servingPath string @@ -186,4 +225,52 @@ func TestFingerprint(t *testing.T) { } } }) + + t.Run("recalculate hashed files only un development", func(t *testing.T) { + fsMap := fstest.MapFS{ + "main.js": {Data: []byte("AAA")}, + } + + m := assets.NewManager(fsMap, assetsPath) + + t.Run("in development mode should recalculate the asset hash", func(t *testing.T) { + t.Setenv("GO_ENV", "development") + + a, err := m.PathFor("main.js") + if err != nil { + t.Errorf("Expected nil, got %s", err) + } + + fsMap["main.js"] = &fstest.MapFile{Data: []byte("BBB")} + + b, err := m.PathFor("main.js") + if err != nil { + t.Errorf("Expected nil, got %s", err) + } + + if a == b { + t.Errorf("Expected %s to not equal %s", a, b) + } + }) + + t.Run("in other env should not recalculate the asset hash", func(t *testing.T) { + t.Setenv("GO_ENV", "production") + + a, err := m.PathFor("main.js") + if err != nil { + t.Errorf("Expected nil, got %s", err) + } + + fsMap["main.js"] = &fstest.MapFile{Data: []byte("CCC")} + + b, err := m.PathFor("main.js") + if err != nil { + t.Errorf("Expected nil, got %s", err) + } + + if a != b { + t.Errorf("Expected %s to equal %s", a, b) + } + }) + }) } diff --git a/assets/manager.go b/assets/manager.go index 716dc06..108e181 100644 --- a/assets/manager.go +++ b/assets/manager.go @@ -24,12 +24,11 @@ func NewManager(embedded fs.FS, servingPath string) *manager { servingPath = "/" } - if !strings.HasPrefix(servingPath, "/") { - servingPath = "/" + servingPath - } - - if !strings.HasSuffix(servingPath, "/") { - servingPath += "/" + servingPath = strings.Trim(servingPath, "/") + if servingPath == "" { + servingPath = "/" + } else { + servingPath = "/" + servingPath + "/" } return &manager{