Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion addons/addon.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ type Addon[T any] struct {

func (a *Addon[T]) RegisterIfNeeded() {
if a.registered.CompareAndSwap(false, true) {
Register(a)
a.register()
}
}

Expand Down
23 changes: 9 additions & 14 deletions addons/bootstrap/apt/dpkg/compare.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,28 +87,23 @@ func StringToVersion(str string) (Version, error) {
}

// Find Epoch
sepEpoch := strings.Index(str, ":")
if sepEpoch > -1 {
intEpoch, err := strconv.Atoi(str[:sepEpoch])
if err == nil {
version.Epoch = intEpoch
} else {
epochStr, str, ok := strings.Cut(str, ":")
if ok {
if intEpoch, err := strconv.Atoi(epochStr); err != nil {
return Version{}, errors.New("epoch in version is not a number")
}
if intEpoch < 0 {
} else if intEpoch < 0 {
return Version{}, errors.New("epoch in version is negative")
} else {
version.Epoch = intEpoch
}
} else {
version.Epoch = 0
str = epochStr
}

// Find UpstreamVersion / DebianRevision
sepDebianRevision := strings.LastIndex(str, "-")
if sepDebianRevision > -1 {
version.UpstreamVersion = str[sepEpoch+1 : sepDebianRevision]
version.DebianRevision = str[sepDebianRevision+1:]
} else {
version.UpstreamVersion = str[sepEpoch+1:]
version.UpstreamVersion, version.DebianRevision, ok = strings.CutLast(str, "-")
if !ok {
version.DebianRevision = "0"
}
// Verify format
Expand Down
12 changes: 6 additions & 6 deletions addons/bootstrap/apt/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,13 @@ const (

// DpkgInstalled returns a map of installed packages to their versions.
func DpkgInstalled(ctx *bootstrap.Context) (map[string]string, error) {
data, ok := bootstrap.Get(ctx, installedKey)
data, ok := ctx.Get(installedKey)
if ok {
if st, err := os.Stat(dpkgStatusFile); err != nil ||
st.ModTime().After(data.timestamp) {
// on-disk file is newer than in memory cache, invalidate it
ok = false
bootstrap.Clear(ctx, installedKey)
ctx.Clear(installedKey)
}
}
if ok {
Expand Down Expand Up @@ -87,18 +87,18 @@ func DpkgInstalled(ctx *bootstrap.Context) (map[string]string, error) {
}
data.data[fields[0]] = fields[1] // package name -> version
}
bootstrap.Save(ctx, installedKey, data)
ctx.Save(installedKey, data)
return data.data, nil
}

func AptAvailable(ctx *bootstrap.Context) (map[string]string, error) {
data, ok := bootstrap.Get(ctx, availableKey)
data, ok := ctx.Get(availableKey)
if ok {
if st, err := os.Stat(aptPkgCacheFile); err != nil ||
st.ModTime().After(data.timestamp) {
// on-disk file is newer than in memory cache, invalidate it
ok = false
bootstrap.Clear(ctx, availableKey)
ctx.Clear(availableKey)
}
}
if ok {
Expand Down Expand Up @@ -145,6 +145,6 @@ func AptAvailable(ctx *bootstrap.Context) (map[string]string, error) {
if err := s.Err(); err != nil {
return nil, fmt.Errorf("error reading apt-cache dumpavail: %w", err)
}
bootstrap.Save(ctx, availableKey, data)
ctx.Save(availableKey, data)
return data.data, nil
}
22 changes: 11 additions & 11 deletions addons/bootstrap/apt/steps-packages.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ func updateStep() *bootstrap.Step {
var sourcesDirty = bootstrap.NewKey[bool]("apt sources dirty")

func DoUpdate(ctx *bootstrap.Context) error {
dirty, ok := bootstrap.Get(ctx, sourcesDirty)
dirty, ok := ctx.Get(sourcesDirty)
// TODO: heuristic if we can skip the update entirely, e.g. if no sources were
// changed and it ran within the last hour or something?
if ok && !dirty {
Expand All @@ -55,14 +55,14 @@ func DoUpdate(ctx *bootstrap.Context) error {
); err != nil {
return err
}
bootstrap.Set(ctx, sourcesDirty, false)
ctx.Set(sourcesDirty, false)
return nil
}

// ChangedSources will mark the apt sources list as dirty, so a secondary
// `apt update` step registered with [WithExtraUpdate] will actually run.
func ChangedSources(ctx *bootstrap.Context) {
bootstrap.Set(ctx, sourcesDirty, true)
ctx.Set(sourcesDirty, true)
}

// Name of the step registered by [AddAptInstall]. This step will install
Expand Down Expand Up @@ -132,10 +132,10 @@ func DoInstall(
extraPackages []string,
sudoPrompt string,
) error {
pkgSet, _ := bootstrap.Get(ctx, pendingPackages)
pkgSet, _ := ctx.Get(pendingPackages)
if pkgSet == nil {
pkgSet = map[string]struct{}{}
bootstrap.Save(ctx, pendingPackages, pkgSet)
ctx.Save(pendingPackages, pkgSet)
}
if len(extraPackages) > 0 {
// don't mutate the stored list
Expand Down Expand Up @@ -180,7 +180,7 @@ func DoInstall(
// clear the pending package list so that a little trickery can install more
// package groups later, e.g. in case setting up some apt source requires
// installing some packages.
bootstrap.Clear(ctx, pendingPackages)
ctx.Clear(pendingPackages)

// assume that installing or upgrading packages requires a reboot. Note that
// we intentionally don't just look at the packages we were asked to install,
Expand All @@ -200,10 +200,10 @@ func InstallNeeded(
ctx *bootstrap.Context,
extras ...string,
) (bool, error) {
pkgSet, _ := bootstrap.Get(ctx, pendingPackages)
pkgSet, _ := ctx.Get(pendingPackages)
if pkgSet == nil {
pkgSet = map[string]struct{}{}
bootstrap.Save(ctx, pendingPackages, pkgSet)
ctx.Save(pendingPackages, pkgSet)
}
if len(extras) > 0 {
// don't mutate the stored list
Expand All @@ -229,7 +229,7 @@ func needsInstall(ctx *bootstrap.Context, set map[string]struct{}) (bool, error)
}

func simInstall(ctx *bootstrap.Context) error {
pkgSet, _ := bootstrap.Get(ctx, pendingPackages)
pkgSet, _ := ctx.Get(pendingPackages)
if len(pkgSet) == 0 {
return nil
}
Expand All @@ -248,10 +248,10 @@ func simInstall(ctx *bootstrap.Context) error {
//
// The caller is responsible for ensuring that such a step runs after this.
func AddPackages(ctx *bootstrap.Context, names ...string) {
pkgSet, _ := bootstrap.Get(ctx, pendingPackages)
pkgSet, _ := ctx.Get(pendingPackages)
if pkgSet == nil {
pkgSet = map[string]struct{}{}
bootstrap.Save(ctx, pendingPackages, pkgSet)
ctx.Save(pendingPackages, pkgSet)
}
added := []string{}
for _, name := range names {
Expand Down
4 changes: 2 additions & 2 deletions addons/bootstrap/context-keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ var skipLoginsKey = NewKey[bool]("bootstrap.skipLogins")
// SkipLogins returns whether login steps should be skipped. This is set by a
// command line argument. Custom bootstrap steps/plans should obey this.
func SkipLogins(ctx *Context) bool {
v, ok := Get(ctx, skipLoginsKey)
v, ok := ctx.Get(skipLoginsKey)
return ok && v
}

Expand All @@ -20,6 +20,6 @@ var headlessKey = NewKey[bool]("bootstrap.headless")
// Headless returns whether steps should run in headless mode. This is set by a
// command line argument. Custom bootstrap steps/plans should obey this.
func Headless(ctx *Context) bool {
v, ok := Get(ctx, headlessKey)
v, ok := ctx.Get(headlessKey)
return ok && v
}
20 changes: 16 additions & 4 deletions addons/bootstrap/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,30 @@ func NewKey[T any](name string) InfoKey[T] {
return internal.NewKey[T](name)
}

// Deprecated: modernize
//
//go:fix inline
func Save[T any](ctx *Context, k InfoKey[T], v T) {
internal.Save(ctx, k, v)
ctx.Save(k, v)
}

// Deprecated: modernize
//
//go:fix inline
func Set[T any](ctx *Context, k InfoKey[T], v T) {
internal.Set(ctx, k, v)
ctx.Set(k, v)
}

// Deprecated: modernize
//
//go:fix inline
func Get[T any](ctx *Context, k InfoKey[T]) (T, bool) {
return internal.Get(ctx, k)
return ctx.Get(k)
}

// Deprecated: modernize
//
//go:fix inline
func Clear[T any](ctx *Context, k InfoKey[T]) {
internal.Clear(ctx, k)
ctx.Clear(k)
}
8 changes: 4 additions & 4 deletions addons/bootstrap/env-detect.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ import (
var isInContainerKey = NewKey[bool]("is-in-container")

func IsInContainer(ctx *Context) bool {
if v, ok := Get(ctx, isInContainerKey); ok {
if v, ok := ctx.Get(isInContainerKey); ok {
return v
}
// TODO: better detection than this
_, err := os.Stat("/.dockerenv")
v := err == nil
Save(ctx, isInContainerKey, v)
ctx.Save(isInContainerKey, v)
return v
}

Expand All @@ -26,11 +26,11 @@ func SkipInContainer() StepOpt {
var hasGUIKey = NewKey[bool]("has-gui")

func HasGUI(ctx *Context) bool {
if v, ok := Get(ctx, hasGUIKey); ok {
if v, ok := ctx.Get(hasGUIKey); ok {
return v
}
v := os.Getenv("DISPLAY") != "" || os.Getenv("WAYLAND_DISPLAY") != ""
Save(ctx, hasGUIKey, v)
ctx.Save(hasGUIKey, v)
return v
}

Expand Down
2 changes: 1 addition & 1 deletion addons/bootstrap/input/go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module fastcat.org/go/gdev/addons/bootstrap/input

go 1.26.6
go 1.27.1

require (
fastcat.org/go/gdev v0.16.0
Expand Down
8 changes: 4 additions & 4 deletions addons/bootstrap/input/prompt.go
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ func (p *Prompter[T]) key() internal.AnyInfoKey {
}

func (p *Prompter[T]) init(ctx *internal.Context) (value T, ok, guessed bool, err error) {
value, ok = internal.Get(ctx, p.infoKey)
value, ok = ctx.Get(p.infoKey)
if ok && p.validator != nil {
if p.validator(value) == nil {
return value, true, false, nil
Expand Down Expand Up @@ -244,7 +244,7 @@ func (p *Prompter[T]) field(ctx *internal.Context) (huh.Field, error) {
if err != nil {
return nil, err
} else if ok && !guessed {
internal.Save(ctx, p.infoKey, value)
ctx.Save(p.infoKey, value)
return nil, nil
}

Expand Down Expand Up @@ -296,7 +296,7 @@ func (p *Prompter[T]) finishForm(
return fmt.Errorf("invalid value: %w", err)
}
}
internal.Set(ctx, p.infoKey, value)
ctx.Set(p.infoKey, value)
var errs []error
for _, writer := range p.writers {
if err := writer(ctx, value); err != nil {
Expand Down Expand Up @@ -341,7 +341,7 @@ func (p *Prompter[T]) Sim(ctx *internal.Context) error {
}
// in a sim (dry run), assume the user would confirm the guess as far as the
// in-memory storage
internal.Save(ctx, p.infoKey, value)
ctx.Save(p.infoKey, value)
if guessed {
fmt.Printf("Would confirm guessed value for %s: %s\n", p.infoKey, p.stringer(value))
} else {
Expand Down
32 changes: 30 additions & 2 deletions addons/bootstrap/internal/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,18 +30,32 @@ func NewEmptyContext(ctx context.Context) *Context {
}
}

// Deprecated: modernize
//
//go:fix inline
func Save[T any](ctx *Context, k InfoKey[T], v T) {
ctx.Save(k, v)
}

// Save stores a value, but only if it is not already set.
//
// If the value is already set, it panics.
func Save[T any](ctx *Context, k InfoKey[T], v T) {
func (ctx *Context) Save[T any](k InfoKey[T], v T) {
if _, ok := ctx.info[k]; ok {
panic(fmt.Errorf("already saved %s for %v", k.k, k.typ()))
}
ctx.info[k] = v
}

// Set is like save, but it will overwrite any existing value as well.
// Deprecated: modernize
//
//go:fix inline
func Set[T any](ctx *Context, k InfoKey[T], v T) {
ctx.Set(k, v)
}

// Set is like save, but it will overwrite any existing value as well.
func (ctx *Context) Set[T any](k InfoKey[T], v T) {
ctx.info[k] = v
}

Expand All @@ -52,7 +66,14 @@ func SetDefault[T any](k InfoKey[T], v T) {
defaults[k] = v
}

// Deprecated: modernize
//
//go:fix inline
func Get[T any](ctx *Context, k InfoKey[T]) (T, bool) {
return ctx.Get(k)
}

func (ctx *Context) Get[T any](k InfoKey[T]) (T, bool) {
v, ok := ctx.info[k]
if !ok {
var t T
Expand All @@ -61,7 +82,14 @@ func Get[T any](ctx *Context, k InfoKey[T]) (T, bool) {
return v.(T), ok
}

// Deprecated: modernize
//
//go:fix inline
func Clear[T any](ctx *Context, k InfoKey[T]) {
ctx.Clear(k)
}

func (ctx *Context) Clear[T any](k InfoKey[T]) {
if _, ok := ctx.info[k]; !ok {
panic(fmt.Errorf("not saved %s for %v", k.k, k.typ()))
}
Expand Down
4 changes: 2 additions & 2 deletions addons/bootstrap/reboot.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ package bootstrap
var needsRebootKey = NewKey[bool]("need-reboot-after-bootstrap")

func SetNeedsReboot(ctx *Context) {
Set(ctx, needsRebootKey, true)
ctx.Set(needsRebootKey, true)
}

func needsReboot(ctx *Context) bool {
v, ok := Get(ctx, needsRebootKey)
v, ok := ctx.Get(needsRebootKey)
return ok && v
}
2 changes: 1 addition & 1 deletion addons/containerd/go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module fastcat.org/go/gdev/addons/containerd

go 1.26.6
go 1.27.1

require (
fastcat.org/go/gdev v0.16.0
Expand Down
2 changes: 1 addition & 1 deletion addons/description.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ type Description struct {

var enabled = map[string]*registration{}

func Register[T any](a *Addon[T]) {
func (a *Addon[T]) register() {
if a.Definition.Name == "" {
panic(fmt.Errorf("addon name required"))
}
Expand Down
Loading