Skip to content

Commit 785a162

Browse files
authored
Merge pull request #58 from GMWalletApp/hot_fix_0427
Hot fix 0427
2 parents 67263da + 0693345 commit 785a162

8 files changed

Lines changed: 745 additions & 335 deletions

File tree

.github/workflows/docker-alpine.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ jobs:
3333
images: ${{ env.DOCKERHUB_NAMESPACE }}/${{ env.IMAGE_NAME }}
3434
tags: |
3535
type=raw,value=alpine
36-
type=raw,value=latest,enable={{is_default_branch}}
36+
type=raw,value=latest
3737
type=ref,event=branch,suffix=-alpine
3838
type=ref,event=tag
3939
type=sha,prefix=sha-,suffix=-alpine

src/config/config.go

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package config
33
import (
44
"errors"
55
"fmt"
6+
"io"
67
"log"
78
"net/url"
89
"os"
@@ -62,6 +63,9 @@ func Init() {
6263
LogLevel = normalizeLogLevel(viper.GetString("log_level"))
6364
StaticPath = normalizeStaticURLPath(viper.GetString("static_path"))
6465
StaticFilePath = filepath.Join(configRootPath, strings.TrimPrefix(StaticPath, "/"))
66+
if err = ensureConfiguredStaticFiles(); err != nil {
67+
panic(err)
68+
}
6569
RuntimePath = resolvePathFromBase(configRootPath, viper.GetString("runtime_root_path"), filepath.Join(configRootPath, "runtime"))
6670
LogSavePath = resolvePathFromBase(RuntimePath, viper.GetString("log_save_path"), filepath.Join(RuntimePath, "logs"))
6771
mustMkdir(RuntimePath)
@@ -82,6 +86,93 @@ func mustMkdir(path string) {
8286
}
8387
}
8488

89+
func ensureConfiguredStaticFiles() error {
90+
if strings.TrimSpace(StaticFilePath) == "" {
91+
return nil
92+
}
93+
exePath, err := os.Executable()
94+
if err != nil {
95+
return err
96+
}
97+
exePath, err = filepath.EvalSymlinks(exePath)
98+
if err != nil {
99+
return err
100+
}
101+
102+
srcDir := filepath.Join(filepath.Dir(exePath), "static")
103+
srcInfo, err := os.Stat(srcDir)
104+
if err != nil {
105+
if errors.Is(err, os.ErrNotExist) {
106+
return nil
107+
}
108+
return err
109+
}
110+
if !srcInfo.IsDir() {
111+
return nil
112+
}
113+
114+
srcAbs, err := filepath.Abs(srcDir)
115+
if err != nil {
116+
return err
117+
}
118+
dstAbs, err := filepath.Abs(StaticFilePath)
119+
if err != nil {
120+
return err
121+
}
122+
if srcAbs == dstAbs {
123+
return nil
124+
}
125+
126+
return copyMissingStaticFiles(srcAbs, dstAbs)
127+
}
128+
129+
func copyMissingStaticFiles(srcDir, dstDir string) error {
130+
return filepath.WalkDir(srcDir, func(path string, d os.DirEntry, err error) error {
131+
if err != nil {
132+
return err
133+
}
134+
rel, err := filepath.Rel(srcDir, path)
135+
if err != nil {
136+
return err
137+
}
138+
dstPath := filepath.Join(dstDir, rel)
139+
if d.IsDir() {
140+
return os.MkdirAll(dstPath, 0o755)
141+
}
142+
if _, err = os.Stat(dstPath); err == nil {
143+
return nil
144+
} else if !errors.Is(err, os.ErrNotExist) {
145+
return err
146+
}
147+
if err = os.MkdirAll(filepath.Dir(dstPath), 0o755); err != nil {
148+
return err
149+
}
150+
return copyFile(path, dstPath)
151+
})
152+
}
153+
154+
func copyFile(srcPath, dstPath string) error {
155+
in, err := os.Open(srcPath)
156+
if err != nil {
157+
return err
158+
}
159+
defer in.Close()
160+
161+
out, err := os.OpenFile(dstPath, os.O_CREATE|os.O_EXCL|os.O_WRONLY, 0o644)
162+
if err != nil {
163+
if errors.Is(err, os.ErrExist) {
164+
return nil
165+
}
166+
return err
167+
}
168+
169+
if _, err = io.Copy(out, in); err != nil {
170+
_ = out.Close()
171+
return err
172+
}
173+
return out.Close()
174+
}
175+
85176
func normalizeLogLevel(level string) string {
86177
switch strings.ToLower(strings.TrimSpace(level)) {
87178
case "debug", "info", "warn", "error":

src/config/config_test.go

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,60 @@ func TestResolveConfigFilePathPrefersExplicitOverEnv(t *testing.T) {
177177
}
178178
}
179179

180+
func TestCopyMissingStaticFilesCopiesAssetsWithoutOverwriting(t *testing.T) {
181+
root := t.TempDir()
182+
src := filepath.Join(root, "app-static")
183+
dst := filepath.Join(root, "data-static")
184+
185+
if err := os.MkdirAll(filepath.Join(src, "images"), 0o755); err != nil {
186+
t.Fatalf("mkdir source: %v", err)
187+
}
188+
if err := os.WriteFile(filepath.Join(src, "index.html"), []byte("source-index"), 0o644); err != nil {
189+
t.Fatalf("write source index: %v", err)
190+
}
191+
if err := os.WriteFile(filepath.Join(src, "payment.js"), []byte("source-payment"), 0o644); err != nil {
192+
t.Fatalf("write source payment: %v", err)
193+
}
194+
if err := os.WriteFile(filepath.Join(src, "images", "logo.png"), []byte("source-logo"), 0o644); err != nil {
195+
t.Fatalf("write source logo: %v", err)
196+
}
197+
198+
if err := os.MkdirAll(dst, 0o755); err != nil {
199+
t.Fatalf("mkdir destination: %v", err)
200+
}
201+
if err := os.WriteFile(filepath.Join(dst, "index.html"), []byte("custom-index"), 0o644); err != nil {
202+
t.Fatalf("write existing destination index: %v", err)
203+
}
204+
205+
if err := copyMissingStaticFiles(src, dst); err != nil {
206+
t.Fatalf("copy missing static files: %v", err)
207+
}
208+
209+
index, err := os.ReadFile(filepath.Join(dst, "index.html"))
210+
if err != nil {
211+
t.Fatalf("read destination index: %v", err)
212+
}
213+
if string(index) != "custom-index" {
214+
t.Fatalf("existing index was overwritten: %q", string(index))
215+
}
216+
217+
payment, err := os.ReadFile(filepath.Join(dst, "payment.js"))
218+
if err != nil {
219+
t.Fatalf("read copied payment: %v", err)
220+
}
221+
if string(payment) != "source-payment" {
222+
t.Fatalf("payment.js = %q, want source-payment", string(payment))
223+
}
224+
225+
logo, err := os.ReadFile(filepath.Join(dst, "images", "logo.png"))
226+
if err != nil {
227+
t.Fatalf("read copied nested asset: %v", err)
228+
}
229+
if string(logo) != "source-logo" {
230+
t.Fatalf("logo.png = %q, want source-logo", string(logo))
231+
}
232+
}
233+
180234
func TestGetUsdtRatePrefersPositiveAdminOverride(t *testing.T) {
181235
viper.Reset()
182236
t.Cleanup(viper.Reset)

0 commit comments

Comments
 (0)