mirror of
https://github.com/CJackHwang/ds2api.git
synced 2026-05-16 06:05:07 +08:00
Document Zeabur manual deployment
This commit is contained in:
@@ -144,6 +144,44 @@ func TestLoadStoreIgnoresLegacyConfigJSONEnv(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestExplicitMissingConfigPathBootstrapsEmptyFileBackedStore(t *testing.T) {
|
||||
path := t.TempDir() + "/config.json"
|
||||
|
||||
t.Setenv("DS2API_CONFIG_JSON", "")
|
||||
t.Setenv("DS2API_CONFIG_PATH", path)
|
||||
|
||||
store, err := LoadStoreWithError()
|
||||
if err != nil {
|
||||
t.Fatalf("expected missing explicit config path to bootstrap, got: %v", err)
|
||||
}
|
||||
if store.IsEnvBacked() {
|
||||
t.Fatal("expected bootstrap store to be file-backed")
|
||||
}
|
||||
if store.ConfigPath() != path {
|
||||
t.Fatalf("ConfigPath() = %q, want %q", store.ConfigPath(), path)
|
||||
}
|
||||
if len(store.Keys()) != 0 || len(store.Accounts()) != 0 {
|
||||
t.Fatalf("expected empty bootstrap config, got keys=%d accounts=%d", len(store.Keys()), len(store.Accounts()))
|
||||
}
|
||||
if _, statErr := os.Stat(path); !errors.Is(statErr, os.ErrNotExist) {
|
||||
t.Fatalf("expected bootstrap not to create config until first save, stat err=%v", statErr)
|
||||
}
|
||||
|
||||
if err := store.Update(func(c *Config) error {
|
||||
c.Keys = []string{"first-key"}
|
||||
return nil
|
||||
}); err != nil {
|
||||
t.Fatalf("update should persist bootstrap config: %v", err)
|
||||
}
|
||||
content, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
t.Fatalf("expected first update to write config: %v", err)
|
||||
}
|
||||
if !strings.Contains(string(content), "first-key") {
|
||||
t.Fatalf("expected saved config to contain first key, got: %s", content)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEnvBackedStoreWritebackBootstrapsMissingConfigFile(t *testing.T) {
|
||||
tmp, err := os.CreateTemp(t.TempDir(), "config-*.json")
|
||||
if err != nil {
|
||||
|
||||
@@ -52,11 +52,12 @@ func loadStore() (*Store, error) {
|
||||
|
||||
func loadConfig() (Config, bool, error) {
|
||||
rawCfg := strings.TrimSpace(os.Getenv("DS2API_CONFIG_JSON"))
|
||||
path := ConfigPath()
|
||||
if rawCfg != "" {
|
||||
cfg, err := parseConfigString(rawCfg)
|
||||
if err != nil {
|
||||
if !IsVercel() && envWritebackEnabled() {
|
||||
if fileCfg, fileErr := loadConfigFromFile(ConfigPath()); fileErr == nil {
|
||||
if fileCfg, fileErr := loadConfigFromFile(path); fileErr == nil {
|
||||
return fileCfg, false, nil
|
||||
}
|
||||
}
|
||||
@@ -67,7 +68,7 @@ func loadConfig() (Config, bool, error) {
|
||||
if IsVercel() || !envWritebackEnabled() {
|
||||
return cfg, true, err
|
||||
}
|
||||
content, fileErr := os.ReadFile(ConfigPath())
|
||||
content, fileErr := os.ReadFile(path)
|
||||
if fileErr == nil {
|
||||
var fileCfg Config
|
||||
if unmarshalErr := json.Unmarshal(content, &fileCfg); unmarshalErr == nil {
|
||||
@@ -79,7 +80,7 @@ func loadConfig() (Config, bool, error) {
|
||||
if validateErr := ValidateConfig(cfg); validateErr != nil {
|
||||
return cfg, true, validateErr
|
||||
}
|
||||
if writeErr := writeConfigFile(ConfigPath(), cfg.Clone()); writeErr == nil {
|
||||
if writeErr := writeConfigFile(path, cfg.Clone()); writeErr == nil {
|
||||
return cfg, false, err
|
||||
} else {
|
||||
Logger.Warn("[config] env writeback bootstrap failed", "error", writeErr)
|
||||
@@ -87,7 +88,7 @@ func loadConfig() (Config, bool, error) {
|
||||
}
|
||||
return cfg, true, err
|
||||
}
|
||||
cfg, err := loadConfigFromFile(ConfigPath())
|
||||
cfg, err := loadConfigFromFile(path)
|
||||
if err != nil {
|
||||
if shouldTryLegacyContainerConfigPath() {
|
||||
legacyPath := legacyContainerConfigPath()
|
||||
@@ -100,6 +101,10 @@ func loadConfig() (Config, bool, error) {
|
||||
// Vercel may start without writable/present config; keep in-memory bootstrap config.
|
||||
return Config{}, true, nil
|
||||
}
|
||||
if shouldBootstrapMissingConfigFile(err) {
|
||||
Logger.Warn("[config] config file missing; starting with empty file-backed config", "path", path)
|
||||
return Config{}, false, nil
|
||||
}
|
||||
return Config{}, false, err
|
||||
}
|
||||
if IsVercel() {
|
||||
@@ -109,6 +114,10 @@ func loadConfig() (Config, bool, error) {
|
||||
return cfg, false, nil
|
||||
}
|
||||
|
||||
func shouldBootstrapMissingConfigFile(err error) bool {
|
||||
return errors.Is(err, os.ErrNotExist) && strings.TrimSpace(os.Getenv("DS2API_CONFIG_PATH")) != ""
|
||||
}
|
||||
|
||||
func loadConfigFromFile(path string) (Config, error) {
|
||||
content, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user