diff --git a/Taskfile.yml b/Taskfile.yml index e1e9ec8..77b972d 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -25,12 +25,26 @@ tasks: - task: cmd-build vars: CMD: convids + build-cool-down: + desc: Builds the cool-down command + source: + - cmd/cool-down/**/*.go + - chill/*.go + - cli/err/*.go + - cli/spin/*.go + generates: + - build/cool-down + cmds: + - task: cmd-build + vars: + CMD: cool-down build-all: desc: Builds all available commands sources: - "**/*.go" generates: - build/convids + - build/cool-down cmds: - task: cmd-build vars: diff --git a/chill/chill.go b/chill/chill.go new file mode 100644 index 0000000..adb7109 --- /dev/null +++ b/chill/chill.go @@ -0,0 +1,47 @@ +package chill + +import ( + "bytes" + "context" + "errors" + "os" + "strconv" + "time" +) + +var TempFile string = "/sys/class/thermal/thermal_zone2/temp" +var MaxTemp int = 72500 +var Sleep = time.Second * 10 +var ErrChilledOut = errors.New("temperature dropped below threshold") + +func Chill(baseCtx context.Context) context.Context { + ctx, cancel := context.WithCancelCause(baseCtx) + + go func() { + var by []byte + var err error + current := MaxTemp + 1 + + for current >= MaxTemp { + by, err = os.ReadFile(TempFile) + if err != nil { + cancel(err) + return + } + + by = bytes.TrimSpace(by) + current, err = strconv.Atoi(string(by)) + if err != nil { + cancel(err) + return + } + if current < MaxTemp { + break + } + time.Sleep(Sleep) + } + cancel(ErrChilledOut) + }() + + return ctx +} diff --git a/cli/spin/spin.go b/cli/spin/spin.go index dd584d8..2896335 100644 --- a/cli/spin/spin.go +++ b/cli/spin/spin.go @@ -58,28 +58,47 @@ func (m model) View() string { return str } -func Spin(ctx context.Context, message string) (chan string, chan error) { - p := tea.NewProgram(newModel(message), tea.WithContext(ctx)) - - msgChan := make(chan string, 10) - errChan := make(chan error) - - go func() { - for { - m := <-msgChan - p.Send(textMessage(m)) - } - }() - go func() { - _, err := p.Run() - if errors.Is(err, context.Canceled) { - err = nil - } else if errors.Is(err, context.DeadlineExceeded) { - err = nil - } else if errors.Is(err, tea.ErrProgramKilled) { - err = nil - } - errChan <- err - }() - return msgChan, errChan +type Spinner interface { + Wait() error + SetMessage(string) + Err() error +} + +var _ Spinner = new(spin) + +type spin struct { + p *tea.Program + err error + finished chan struct{} +} + +func (s *spin) Wait() error { + <-s.finished + return s.Err() +} + +func (s *spin) SetMessage(msg string) { + s.p.Send(textMessage(msg)) +} + +func (s *spin) Err() error { + if errors.Is(s.err, context.Canceled) { + return nil + } else if errors.Is(s.err, context.DeadlineExceeded) { + return nil + } else if errors.Is(s.err, tea.ErrProgramKilled) { + return nil + } + return s.err +} + +func Spin(ctx context.Context, message string) Spinner { + p := tea.NewProgram(newModel(message), tea.WithContext(ctx)) + s := &spin{p: p, finished: make(chan struct{}, 1)} + go func() { + _, err := s.p.Run() + s.err = err + s.finished <- struct{}{} + }() + return s } diff --git a/cmd/cool-down/main.go b/cmd/cool-down/main.go new file mode 100644 index 0000000..18487b1 --- /dev/null +++ b/cmd/cool-down/main.go @@ -0,0 +1,16 @@ +package main + +import ( + "context" + + "codeberg.org/danjones000/utils/chill" + e "codeberg.org/danjones000/utils/cli/err" + "codeberg.org/danjones000/utils/cli/spin" +) + +func main() { + ctx := chill.Chill(context.Background()) + s := spin.Spin(ctx, "Waiting for CPU to cool...") + err := s.Wait() + e.HandleErr(err) +}