Skip to content

Commit

Permalink
Merge pull request #26 from leapkit/fix-recalculate-asset-hashes
Browse files Browse the repository at this point in the history
fix(assets): recalculate assets hashes in development mode
  • Loading branch information
paganotoni authored Feb 24, 2025
2 parents a5c7d0f + 0923a95 commit 1ee12d7
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 10 deletions.
13 changes: 10 additions & 3 deletions assets/fingerprint.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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

Expand Down
89 changes: 88 additions & 1 deletion assets/fingerprint_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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")},
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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)
}
})
})
}
11 changes: 5 additions & 6 deletions assets/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -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{
Expand Down

0 comments on commit 1ee12d7

Please sign in to comment.