Sample env carries a version marker; install appends settings missing since the writing version
This commit is contained in:
+110
-14
@@ -2,6 +2,7 @@ package config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
@@ -14,12 +15,14 @@ type sampleEntry struct {
|
||||
active bool // rendered uncommented
|
||||
}
|
||||
|
||||
// SampleEnv renders a sample .env file covering every setting, each with a
|
||||
// comment line. Everything is commented out — so all defaults apply —
|
||||
// except LOG_FILE when logFile is non-empty: a Windows service has no
|
||||
// console, so the installer pre-wires file logging there.
|
||||
func SampleEnv(logFile string) string {
|
||||
entries := []sampleEntry{
|
||||
// versionMarker prefixes the first line of an installer-written env file so
|
||||
// later installs can tell which version wrote it.
|
||||
const versionMarker = "# gpu-turnstile version: "
|
||||
|
||||
// sampleEntries lists every setting in sample order. logFile activates the
|
||||
// LOG_FILE line (Windows install); empty keeps it commented like the rest.
|
||||
func sampleEntries(logFile string) []sampleEntry {
|
||||
return []sampleEntry{
|
||||
{"LISTEN_OLLAMA", ":11434", "Ollama-facing listener address", false},
|
||||
{"LISTEN_COMFY", ":8188", "ComfyUI-facing listener address", false},
|
||||
{"OLLAMA_URL", "http://127.0.0.1:11434", "Ollama upstream URL; setting it enables the Ollama consumer (default: empty = disabled)", false},
|
||||
@@ -48,18 +51,111 @@ func SampleEnv(logFile string) string {
|
||||
{"UPDATE_REPO", "https://git.rambossek.at/PUBLIC/gpu-turnstile", "Repository to check for releases", false},
|
||||
{"UPDATE_ASSET", "gpu-turnstile.exe", "Release asset to download", false},
|
||||
}
|
||||
}
|
||||
|
||||
// SampleEnv renders a sample .env file covering every setting, each with a
|
||||
// comment line. Everything is commented out — so all defaults apply —
|
||||
// except LOG_FILE when logFile is non-empty: a Windows service has no
|
||||
// console, so the installer pre-wires file logging there. The first line
|
||||
// carries the writing version so later installs can upgrade the file.
|
||||
func SampleEnv(version, logFile string) string {
|
||||
var b strings.Builder
|
||||
b.WriteString("# gpu-turnstile configuration\n")
|
||||
b.WriteString(versionMarker + version + "\n")
|
||||
b.WriteString("# KEY=VALUE lines; \"#\" starts a comment. Every setting below is at its\n")
|
||||
b.WriteString("# default and commented out — remove the \"#\" to change it.\n")
|
||||
b.WriteString("# At least one of OLLAMA_URL / COMFY_URL must be set for the proxy to start.\n\n")
|
||||
for _, e := range entries {
|
||||
fmt.Fprintf(&b, "# %s\n", e.comment)
|
||||
if e.active {
|
||||
fmt.Fprintf(&b, "%s=%s\n\n", e.name, e.value)
|
||||
} else {
|
||||
fmt.Fprintf(&b, "#%s=%s\n\n", e.name, e.value)
|
||||
}
|
||||
for _, e := range sampleEntries(logFile) {
|
||||
writeEntry(&b, e)
|
||||
}
|
||||
return b.String()
|
||||
}
|
||||
|
||||
func writeEntry(b *strings.Builder, e sampleEntry) {
|
||||
fmt.Fprintf(b, "# %s\n", e.comment)
|
||||
if e.active {
|
||||
fmt.Fprintf(b, "%s=%s\n\n", e.name, e.value)
|
||||
} else {
|
||||
fmt.Fprintf(b, "#%s=%s\n\n", e.name, e.value)
|
||||
}
|
||||
}
|
||||
|
||||
// SyncSample upgrades an installer-written env file: when its version
|
||||
// marker says it was written by an older gpu-turnstile, every setting the
|
||||
// file does not mention — commented or not — is appended at the end, and
|
||||
// the marker is updated to version. Files without the marker (hand-written
|
||||
// configs) and up-to-date files are returned unchanged; changed reports
|
||||
// whether the returned content differs. A "dev" version never upgrades.
|
||||
func SyncSample(data, version, logFile string) (string, bool) {
|
||||
if version == "" || version == "dev" {
|
||||
return data, false
|
||||
}
|
||||
first, _, _ := strings.Cut(data, "\n")
|
||||
marker, ok := strings.CutPrefix(first, versionMarker)
|
||||
if !ok {
|
||||
return data, false // not written by the installer
|
||||
}
|
||||
if compareVersions(strings.TrimSpace(marker), version) >= 0 {
|
||||
return data, false // same or newer
|
||||
}
|
||||
|
||||
present := make(map[string]bool)
|
||||
for _, line := range strings.Split(data, "\n") {
|
||||
line = strings.TrimSpace(strings.TrimPrefix(strings.TrimSpace(line), "#"))
|
||||
if name, _, ok := strings.Cut(line, "="); ok {
|
||||
present[strings.TrimSpace(name)] = true
|
||||
}
|
||||
}
|
||||
|
||||
var b strings.Builder
|
||||
b.WriteString(versionMarker + version + "\n")
|
||||
rest := strings.TrimPrefix(data, first)
|
||||
b.WriteString(strings.TrimRight(rest, "\n"))
|
||||
b.WriteString("\n")
|
||||
for _, e := range sampleEntries(logFile) {
|
||||
if !present[e.name] {
|
||||
fmt.Fprintf(&b, "\n# Added by gpu-turnstile %s:\n", version)
|
||||
writeEntry(&b, e)
|
||||
}
|
||||
}
|
||||
out := b.String()
|
||||
return out, out != data
|
||||
}
|
||||
|
||||
// compareVersions orders two vX.Y.Z version strings. Unparseable versions
|
||||
// (including "dev") sort before any release.
|
||||
func compareVersions(a, b string) int {
|
||||
pa, oka := parseVersion(a)
|
||||
pb, okb := parseVersion(b)
|
||||
if oka != okb {
|
||||
if oka {
|
||||
return 1
|
||||
}
|
||||
return -1
|
||||
}
|
||||
for i := range pa {
|
||||
if pa[i] != pb[i] {
|
||||
if pa[i] > pb[i] {
|
||||
return 1
|
||||
}
|
||||
return -1
|
||||
}
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func parseVersion(v string) ([3]int, bool) {
|
||||
var out [3]int
|
||||
v = strings.TrimPrefix(strings.TrimSpace(v), "v")
|
||||
parts := strings.Split(v, ".")
|
||||
if len(parts) != 3 {
|
||||
return out, false
|
||||
}
|
||||
for i, p := range parts {
|
||||
n, err := strconv.Atoi(p)
|
||||
if err != nil || n < 0 {
|
||||
return out, false
|
||||
}
|
||||
out[i] = n
|
||||
}
|
||||
return out, true
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user