Files
galaxy-game/lobby/internal/domain/engineimage/resolver.go
T
2026-04-28 20:39:18 +02:00

67 lines
2.4 KiB
Go

// Package engineimage resolves the Docker reference Lobby publishes on
// `runtime:start_jobs`. The reference is built from a configurable
// template that must contain the literal `{engine_version}` placeholder
// and a per-game `target_engine_version`.
//
// The resolver intentionally performs only template substitution and a
// non-empty-version guard. Semver validation of the engine version
// itself lives in `lobby/internal/domain/game` and runs at game-record
// construction time; by the time `startgame.Service.Handle` reads the
// record the version is already validated.
package engineimage
import (
"errors"
"fmt"
"strings"
)
// VersionPlaceholder is the literal token a template must contain. The
// resolver substitutes it with the per-game engine version verbatim.
const VersionPlaceholder = "{engine_version}"
// Resolver substitutes a per-game engine version into a pre-validated
// template. The template is validated once at construction so per-game
// `Resolve` calls remain pure string substitution.
type Resolver struct {
template string
}
// NewResolver returns a Resolver that uses template for every Resolve
// call. It returns an error if template is empty or does not contain
// VersionPlaceholder.
func NewResolver(template string) (*Resolver, error) {
trimmed := strings.TrimSpace(template)
if trimmed == "" {
return nil, errors.New("engine image resolver: template must not be empty")
}
if !strings.Contains(trimmed, VersionPlaceholder) {
return nil, fmt.Errorf(
"engine image resolver: template %q must contain placeholder %q",
template, VersionPlaceholder,
)
}
return &Resolver{template: trimmed}, nil
}
// Template returns the validated template string the resolver was
// constructed with. The accessor is intended for diagnostics and tests.
func (resolver *Resolver) Template() string {
if resolver == nil {
return ""
}
return resolver.template
}
// Resolve substitutes VersionPlaceholder in the validated template with
// version. It returns an error when version is empty or whitespace.
func (resolver *Resolver) Resolve(version string) (string, error) {
if resolver == nil {
return "", errors.New("engine image resolver: nil resolver")
}
if strings.TrimSpace(version) == "" {
return "", errors.New("engine image resolver: engine version must not be empty")
}
return strings.ReplaceAll(resolver.template, VersionPlaceholder, version), nil
}