aboutsummaryrefslogtreecommitdiffhomepage
path: root/internal/app/app.go
diff options
context:
space:
mode:
authorOphestra <cat@gensokyo.uk>2025-09-24 18:44:14 +0900
committerOphestra <cat@gensokyo.uk>2025-09-24 18:44:14 +0900
commit1c4f593566943d8a0ce16eb3cae77f8c50238202 (patch)
tree2ac5c41a84127ff4cd5a275c81e834c495a109c9 /internal/app/app.go
parentb99c63337df4068b36d7d8de2ae79fd274172977 (diff)
internal/app: unexport outcome, remove app struct
The App struct no longer does anything, and the outcome struct is entirely opaque. Signed-off-by: Ophestra <cat@gensokyo.uk>
Diffstat (limited to 'internal/app/app.go')
-rw-r--r--internal/app/app.go81
1 files changed, 13 insertions, 68 deletions
diff --git a/internal/app/app.go b/internal/app/app.go
index dd34cf62..4ecf1cc0 100644
--- a/internal/app/app.go
+++ b/internal/app/app.go
@@ -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")
}