adding more functions to media managament system
This commit is contained in:
parent
95e62c2d77
commit
70c0ba44f0
30 changed files with 1494 additions and 104 deletions
|
|
@ -133,3 +133,56 @@ func TestWriteEnvValuesRoundTrip(t *testing.T) {
|
|||
t.Error(".env lost .env.example's comment lines on write")
|
||||
}
|
||||
}
|
||||
|
||||
// TestWriteEnvValuesPreservesUnrelatedCustomValues guards against a real
|
||||
// regression: a save that only touches one section's keys used to reset
|
||||
// every OTHER already-customized key (e.g. TELESRV_ADMIN_UI_PASSWORD) back
|
||||
// to .env.example's bare template default, because the old implementation
|
||||
// fell back to the template line instead of the current .env value for any
|
||||
// key missing from that save's payload.
|
||||
func TestWriteEnvValuesPreservesUnrelatedCustomValues(t *testing.T) {
|
||||
root := findRepoRoot(t)
|
||||
tmpl, err := os.ReadFile(filepath.Join(root, ".env.example"))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
dir := t.TempDir()
|
||||
if err := os.WriteFile(filepath.Join(dir, ".env.example"), tmpl, 0o644); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
m := NewManager(dir)
|
||||
|
||||
// First save sets the admin password, as a one-time setup step would.
|
||||
if err := m.WriteEnvValues(map[string]string{
|
||||
"TELESRV_ADMIN_UI_PASSWORD": "s3cret",
|
||||
}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// A later, unrelated save (e.g. the Storage page) that never mentions
|
||||
// the password must not disturb it.
|
||||
if err := m.WriteEnvValues(map[string]string{
|
||||
"TELESRV_STORAGE_MAX_TOTAL_BYTES": "209715200",
|
||||
}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
groups, err := m.ReadEnvGroups()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
values := map[string]string{}
|
||||
for _, g := range groups {
|
||||
for _, f := range g.Fields {
|
||||
values[f.Key] = f.Value
|
||||
}
|
||||
}
|
||||
if values["TELESRV_ADMIN_UI_PASSWORD"] != "s3cret" {
|
||||
t.Errorf("TELESRV_ADMIN_UI_PASSWORD = %q, want it preserved as \"s3cret\" after an unrelated save", values["TELESRV_ADMIN_UI_PASSWORD"])
|
||||
}
|
||||
if values["TELESRV_STORAGE_MAX_TOTAL_BYTES"] != "209715200" {
|
||||
t.Errorf("TELESRV_STORAGE_MAX_TOTAL_BYTES = %q, want 209715200", values["TELESRV_STORAGE_MAX_TOTAL_BYTES"])
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -637,15 +637,25 @@ func (m *Manager) readEnvFile() (map[string]string, error) {
|
|||
// WriteEnvValues rewrites .env from .env.example's exact text, substituting
|
||||
// each known key's value in place -- see save_env()'s docstring in
|
||||
// server-panel.py for why this (not a fresh key=value dump) is what
|
||||
// preserves comments/layout. Only keys present in values are touched; a
|
||||
// template-commented optional field is uncommented when given a non-empty
|
||||
// value and left as-is when given an empty one.
|
||||
// preserves comments/layout. Only keys present in values are set to a new
|
||||
// value; every other key keeps whatever is already in the current .env
|
||||
// (falling back to the template's own default only for a key .env never
|
||||
// set) -- previously this fell straight back to the template default for
|
||||
// any key not in this particular save's payload, silently wiping out every
|
||||
// other customized setting (e.g. TELESRV_ADMIN_UI_PASSWORD) on every save
|
||||
// that only touches one section's keys. A template-commented optional field
|
||||
// is uncommented when given a non-empty value and left as-is when given an
|
||||
// empty one.
|
||||
func (m *Manager) WriteEnvValues(values map[string]string) error {
|
||||
tmplPath := filepath.Join(m.Root, ".env.example")
|
||||
tmplData, err := os.ReadFile(tmplPath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("read .env.example: %w", err)
|
||||
}
|
||||
existing, err := m.readEnvFile()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
lines := strings.Split(string(tmplData), "\n")
|
||||
// Split() on a trailing "\n" leaves one empty trailing element; drop it
|
||||
// so the join below doesn't add a spurious blank line before the final
|
||||
|
|
@ -657,15 +667,20 @@ func (m *Manager) WriteEnvValues(values map[string]string) error {
|
|||
seen := map[string]bool{}
|
||||
for _, raw := range lines {
|
||||
line := strings.TrimSpace(raw)
|
||||
if a := activeFieldRe.FindStringSubmatch(line); a != nil {
|
||||
if v, ok := values[a[1]]; ok && !seen[a[1]] {
|
||||
if a := activeFieldRe.FindStringSubmatch(line); a != nil && !seen[a[1]] {
|
||||
if v, ok := values[a[1]]; ok {
|
||||
seen[a[1]] = true
|
||||
out = append(out, a[1]+"="+v)
|
||||
continue
|
||||
}
|
||||
if v, ok := existing[a[1]]; ok {
|
||||
seen[a[1]] = true
|
||||
out = append(out, a[1]+"="+v)
|
||||
continue
|
||||
}
|
||||
}
|
||||
if c := commentedFieldRe.FindStringSubmatch(line); c != nil {
|
||||
if v, ok := values[c[1]]; ok && !seen[c[1]] {
|
||||
if c := commentedFieldRe.FindStringSubmatch(line); c != nil && !seen[c[1]] {
|
||||
if v, ok := values[c[1]]; ok {
|
||||
seen[c[1]] = true
|
||||
if v != "" {
|
||||
out = append(out, c[1]+"="+v)
|
||||
|
|
@ -674,6 +689,14 @@ func (m *Manager) WriteEnvValues(values map[string]string) error {
|
|||
}
|
||||
continue
|
||||
}
|
||||
// A previously-enabled optional field shows up in the current
|
||||
// .env as an active line even though the template still has it
|
||||
// commented out -- keep it enabled with its existing value.
|
||||
if v, ok := existing[c[1]]; ok {
|
||||
seen[c[1]] = true
|
||||
out = append(out, c[1]+"="+v)
|
||||
continue
|
||||
}
|
||||
}
|
||||
out = append(out, raw)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue