internal/app: unexport outcome, remove app struct
All checks were successful
Test / Create distribution (push) Successful in 34s
Test / Sandbox (push) Successful in 2m14s
Test / Hakurei (race detector) (push) Successful in 5m20s
Test / Hpkg (push) Successful in 41s
Test / Hakurei (push) Successful in 2m20s
Test / Sandbox (race detector) (push) Successful in 2m9s
Test / Flake checks (push) Successful in 1m30s
All checks were successful
Test / Create distribution (push) Successful in 34s
Test / Sandbox (push) Successful in 2m14s
Test / Hakurei (race detector) (push) Successful in 5m20s
Test / Hpkg (push) Successful in 41s
Test / Hakurei (push) Successful in 2m20s
Test / Sandbox (race detector) (push) Successful in 2m9s
Test / Flake checks (push) Successful in 1m30s
The App struct no longer does anything, and the outcome struct is entirely opaque. Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
@@ -3,83 +3,28 @@ package app
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"sync"
|
||||
"os"
|
||||
|
||||
"hakurei.app/hst"
|
||||
"hakurei.app/internal/app/state"
|
||||
"hakurei.app/internal/sys"
|
||||
)
|
||||
|
||||
// New returns the address of a newly initialised [App] struct.
|
||||
func New(ctx context.Context, os sys.State) (*App, error) {
|
||||
a := new(App)
|
||||
a.sys = os
|
||||
a.ctx = ctx
|
||||
|
||||
id := new(state.ID)
|
||||
err := state.NewAppID(id)
|
||||
a.id = newID(id)
|
||||
|
||||
return a, err
|
||||
}
|
||||
|
||||
// MustNew calls [New] and panics if an error is returned.
|
||||
func MustNew(ctx context.Context, os sys.State) *App {
|
||||
a, err := New(ctx, os)
|
||||
if err != nil {
|
||||
log.Fatalf("cannot create app: %v", err)
|
||||
}
|
||||
return a
|
||||
}
|
||||
|
||||
// An App keeps track of the hakurei container lifecycle.
|
||||
type App struct {
|
||||
outcome *Outcome
|
||||
|
||||
id *stringPair[state.ID]
|
||||
sys sys.State
|
||||
ctx context.Context
|
||||
mu sync.RWMutex
|
||||
}
|
||||
|
||||
// ID returns a copy of [state.ID] held by App.
|
||||
func (a *App) ID() state.ID { a.mu.RLock(); defer a.mu.RUnlock(); return a.id.unwrap() }
|
||||
|
||||
func (a *App) String() string {
|
||||
if a == nil {
|
||||
return "<nil>"
|
||||
// Main runs an app according to [hst.Config] and terminates. Main does not return.
|
||||
func Main(ctx context.Context, k sys.State, config *hst.Config) {
|
||||
var id state.ID
|
||||
if err := state.NewAppID(&id); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
a.mu.RLock()
|
||||
defer a.mu.RUnlock()
|
||||
|
||||
if a.outcome != nil {
|
||||
if a.outcome.user.uid == nil {
|
||||
return "<invalid>"
|
||||
}
|
||||
return fmt.Sprintf("sealed app %s as uid %s", a.id, a.outcome.user.uid)
|
||||
var seal outcome
|
||||
seal.id = &stringPair[state.ID]{id, id.String()}
|
||||
if err := seal.finalise(ctx, k, config); err != nil {
|
||||
printMessageError("cannot seal app:", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
return fmt.Sprintf("unsealed app %s", a.id)
|
||||
}
|
||||
|
||||
// Seal determines the [Outcome] of [hst.Config].
|
||||
// Values stored in and referred to by [hst.Config] might be overwritten and must not be used again.
|
||||
func (a *App) Seal(config *hst.Config) (*Outcome, error) {
|
||||
a.mu.Lock()
|
||||
defer a.mu.Unlock()
|
||||
|
||||
if a.outcome != nil {
|
||||
panic("attempting to seal app twice")
|
||||
}
|
||||
|
||||
seal := new(Outcome)
|
||||
seal.id = a.id
|
||||
err := seal.finalise(a.ctx, a.sys, config)
|
||||
if err == nil {
|
||||
a.outcome = seal
|
||||
}
|
||||
return seal, err
|
||||
seal.main()
|
||||
panic("unreachable")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user