Skip to content

Commit b126966

Browse files
fix: restore persistence functionality
This commit addresses an issue where the switch to using systemd templates and format specifiers introduced a regression, causing the persistence functionality to no longer work as expected. To resolve this issue, we have reverted to an earlier implementation that manually writes all the units and uses Go's exec.LookPath to resolve the shell path. Resolves: #65
1 parent 7f0908d commit b126966

File tree

3 files changed

+56
-26
lines changed

3 files changed

+56
-26
lines changed

bat.service

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
[Unit]
2+
Description=Persist the battery charging threshold after {{.Event}}
3+
After={{.Event}}.target
4+
StartLimitBurst=0
5+
6+
[Service]
7+
Type=oneshot
8+
ExecStart={{.Shell}} -c 'echo {{.Threshold}} > /sys/class/power_supply/BAT?/charge_control_end_threshold'
9+
Restart=on-failure
10+
RemainAfterExit=true
11+
12+
[Install]
13+
WantedBy={{.Event}}.target

[email protected]

Lines changed: 0 additions & 12 deletions
This file was deleted.

main_linux.go

Lines changed: 43 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import (
1515
"strconv"
1616
"strings"
1717
"syscall"
18+
"text/template"
1819
"time"
1920

2021
"golang.org/x/sys/unix"
@@ -23,10 +24,10 @@ import (
2324
const (
2425
device = "/sys/class/power_supply/BAT?"
2526
threshold = "charge_control_end_threshold"
26-
service = "/etc/systemd/system/[email protected]"
27+
services = "/etc/systemd/system/"
2728
)
2829

29-
var targets = [...]string{
30+
var events = [...]string{
3031
"hibernate",
3132
"hybrid-sleep",
3233
"multi-user",
@@ -37,7 +38,7 @@ var targets = [...]string{
3738
var build, tag string
3839

3940
var (
40-
//go:embed bat@.service
41+
//go:embed bat.service
4142
unit string
4243
//go:embed help.fmt
4344
help string
@@ -141,16 +142,43 @@ func main() {
141142
if err != nil {
142143
log.Fatal(err)
143144
}
144-
tmpl := fmt.Sprintf(unit, current)
145-
if err := os.WriteFile(service, []byte(tmpl), 0o644); err != nil {
146-
if errors.Is(err, syscall.EACCES) {
147-
fmt.Fprintln(os.Stderr, "Permission denied. Try running this command using sudo.")
145+
146+
shell, err := exec.LookPath("bash")
147+
if err != nil {
148+
if errors.Is(err, exec.ErrNotFound) {
149+
fmt.Fprintln(os.Stderr, "Could not find Bash on your system.")
148150
os.Exit(1)
149151
}
150152
log.Fatal(err)
151153
}
152-
for _, target := range targets {
153-
cmd := exec.Command("systemctl", "enable", fmt.Sprintf("bat@%s.service", target))
154+
155+
for _, event := range events {
156+
tmpl, err := template.New("unit").Parse(unit)
157+
if err != nil {
158+
log.Fatal(err)
159+
}
160+
161+
name := services + "bat-" + event + ".service"
162+
f, err := os.Create(name)
163+
if err != nil {
164+
if errors.Is(err, syscall.EACCES) {
165+
fmt.Fprintln(os.Stderr, "Permission denied. Try running this command using sudo.")
166+
os.Exit(1)
167+
}
168+
log.Fatal(err)
169+
}
170+
defer f.Close()
171+
172+
service := struct {
173+
Event string
174+
Shell string
175+
Threshold int
176+
}{event, shell, current}
177+
if err := tmpl.Execute(f, service); err != nil {
178+
log.Fatal(err)
179+
}
180+
181+
cmd := exec.Command("systemctl", "enable", name)
154182
if err := cmd.Run(); err != nil {
155183
log.Fatal(err)
156184
}
@@ -202,9 +230,10 @@ func main() {
202230
fmt.Fprintln(os.Stdout, "Charging threshold set.\nRun `sudo bat persist` to persist the setting between restarts.")
203231
}
204232
case "reset":
205-
for _, target := range targets {
233+
for _, event := range events {
234+
name := services + "bat-" + event + ".service"
206235
buf := new(bytes.Buffer)
207-
cmd := exec.Command("systemctl", "disable", fmt.Sprintf("bat@%s.service", target))
236+
cmd := exec.Command("systemctl", "disable", name)
208237
cmd.Stderr = buf
209238
if err := cmd.Run(); err != nil {
210239
switch message := buf.String(); {
@@ -217,9 +246,9 @@ func main() {
217246
log.Fatal(err)
218247
}
219248
}
220-
}
221-
if err := os.Remove(service); err != nil && !errors.Is(err, syscall.ENOENT) {
222-
log.Fatal(err)
249+
if err := os.Remove(name); err != nil && !errors.Is(err, syscall.ENOENT) {
250+
log.Fatal(err)
251+
}
223252
}
224253
fmt.Fprintln(os.Stdout, "Charging threshold persistence reset.")
225254
default:

0 commit comments

Comments
 (0)