mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-10-23 03:34:01 -04:00
systemd: start enabled service on restart when idle
Port 2.0
(cherry picked from commit 5a20a8f162)
This commit is contained in:
@@ -20,9 +20,16 @@ var runSystemctl = func(args ...string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// Assigned in init: shellApp's config refers back to trySystemdRestart.
|
||||
var shellRunning func() bool
|
||||
|
||||
func init() {
|
||||
shellRunning = func() bool { return len(shellApp.PIDs()) > 0 }
|
||||
}
|
||||
|
||||
func trySystemdRestart() (bool, error) {
|
||||
if err := runSystemctl("--user", "is-active", "--quiet", dmsSystemdUnit); err != nil {
|
||||
return false, nil
|
||||
return trySystemdStart()
|
||||
}
|
||||
|
||||
if err := runSystemctl("--user", "restart", dmsSystemdUnit); err != nil {
|
||||
@@ -30,3 +37,23 @@ func trySystemdRestart() (bool, error) {
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// With nothing running, restart would spawn an unmanaged daemon that blocks
|
||||
// the unit once the session target starts it. A running hand-started
|
||||
// instance is left to the plain restart path.
|
||||
func trySystemdStart() (bool, error) {
|
||||
if shellRunning() {
|
||||
return false, nil
|
||||
}
|
||||
if err := runSystemctl("--user", "is-enabled", "--quiet", dmsSystemdUnit); err != nil {
|
||||
return false, nil
|
||||
}
|
||||
if err := runSystemctl("--user", "is-active", "--quiet", "graphical-session.target"); err != nil {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
if err := runSystemctl("--user", "start", dmsSystemdUnit); err != nil {
|
||||
return true, fmt.Errorf("starting %s: %w", dmsSystemdUnit, err)
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"slices"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestTrySystemdRestart(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
running bool
|
||||
ok []string
|
||||
wantHandled bool
|
||||
wantCall string
|
||||
}{
|
||||
{"active unit restarts", false, []string{"is-active dms.service", "restart"}, true, "restart dms.service"},
|
||||
{"enabled inactive unit starts", false, []string{"is-enabled", "is-active graphical-session.target", "start"}, true, "start dms.service"},
|
||||
{"hand-started instance keeps plain restart", true, []string{"is-enabled", "is-active graphical-session.target", "start"}, false, ""},
|
||||
{"session target not up", false, []string{"is-enabled"}, false, ""},
|
||||
{"unit disabled", false, []string{"is-active graphical-session.target"}, false, ""},
|
||||
{"no systemd", false, nil, false, ""},
|
||||
}
|
||||
|
||||
origSystemctl, origRunning := runSystemctl, shellRunning
|
||||
t.Cleanup(func() { runSystemctl, shellRunning = origSystemctl, origRunning })
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
shellRunning = func() bool { return tt.running }
|
||||
var calls []string
|
||||
runSystemctl = func(args ...string) error {
|
||||
call := strings.Join(slices.DeleteFunc(slices.Clone(args), func(a string) bool {
|
||||
return strings.HasPrefix(a, "--")
|
||||
}), " ")
|
||||
calls = append(calls, call)
|
||||
for _, prefix := range tt.ok {
|
||||
if strings.HasPrefix(call, prefix) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return errors.New("exit status 3")
|
||||
}
|
||||
|
||||
handled, err := trySystemdRestart()
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if handled != tt.wantHandled {
|
||||
t.Fatalf("handled = %v, want %v (calls %q)", handled, tt.wantHandled, calls)
|
||||
}
|
||||
if tt.wantCall != "" && !slices.Contains(calls, tt.wantCall) {
|
||||
t.Fatalf("missing %q in calls %q", tt.wantCall, calls)
|
||||
}
|
||||
if !tt.wantHandled && slices.ContainsFunc(calls, func(c string) bool { return strings.HasPrefix(c, "start") }) {
|
||||
t.Fatalf("unexpected start in calls %q", calls)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -9,7 +9,7 @@ require (
|
||||
github.com/charmbracelet/bubbletea v1.3.10
|
||||
github.com/charmbracelet/lipgloss v1.1.0
|
||||
github.com/dlclark/regexp2/v2 v2.9.1
|
||||
github.com/duxlabs-dev/dux-go v1.6.3-0.20261020163124-e2ca52bdf500
|
||||
github.com/duxlabs-dev/dux-go v1.6.3-0.20261023041949-220eb5ff21dc
|
||||
github.com/duxlabs-dev/dux-gop v1.6.3-0.20261020163819-0e4888f1fcea
|
||||
github.com/fsnotify/fsnotify v1.10.1
|
||||
github.com/go-git/go-git/v6 v6.0.0-beta.1
|
||||
|
||||
+2
-2
@@ -97,8 +97,8 @@ github.com/digitalocean/go-smbios v0.0.0-20180907143718-390a4f403a8e h1:vUmf0yez
|
||||
github.com/digitalocean/go-smbios v0.0.0-20180907143718-390a4f403a8e/go.mod h1:YTIHhz/QFSYnu/EhlF2SpU2Uk+32abacUYA5ZPljz1A=
|
||||
github.com/dlclark/regexp2/v2 v2.9.1 h1:q6bZW/NN9VodqMjYXpuic2lZxdHPfFTzGS+MJxIJmKQ=
|
||||
github.com/dlclark/regexp2/v2 v2.9.1/go.mod h1:avUrQvPaLz2DrFNHJF0taWAFFX2C1GMSSoeiqFjcBmU=
|
||||
github.com/duxlabs-dev/dux-go v1.6.3-0.20261020163124-e2ca52bdf500 h1:y02m7QgoX4rwauY9HePIPGCRDJ/fMirBmgj78IkeUsc=
|
||||
github.com/duxlabs-dev/dux-go v1.6.3-0.20261020163124-e2ca52bdf500/go.mod h1:b+hBqIgOVAmlFKJ+33SY2pH4kJjXpifNeioPMxwC4Nk=
|
||||
github.com/duxlabs-dev/dux-go v1.6.3-0.20261023041949-220eb5ff21dc h1:oZhWdM7mlEevEm1zaeOeDfIMQkvtZSW8UNqrAZldbAY=
|
||||
github.com/duxlabs-dev/dux-go v1.6.3-0.20261023041949-220eb5ff21dc/go.mod h1:b+hBqIgOVAmlFKJ+33SY2pH4kJjXpifNeioPMxwC4Nk=
|
||||
github.com/duxlabs-dev/dux-gop v1.6.3-0.20261020163819-0e4888f1fcea h1:+z9uPtBmpXXBPupB6++/8avPA0weOkzAz7jBoE+yIok=
|
||||
github.com/duxlabs-dev/dux-gop v1.6.3-0.20261020163819-0e4888f1fcea/go.mod h1:IYu4GO7zR61w3+tDmjg71dQDInXe5TcP3lHQqJpZYR0=
|
||||
github.com/ebitengine/purego v0.11.2 h1:WWiTx8rD8zYdOwSj8O/NiNbsOvSAgJMTlyV1XlbUSeU=
|
||||
|
||||
Reference in New Issue
Block a user