execute command on state change

This commit is contained in:
Sam Boysel 2022-05-30 23:20:58 -07:00
parent 6236144041
commit 3d3a2bc152
3 changed files with 51 additions and 0 deletions

View File

@ -65,6 +65,27 @@ Example:
}
```
### Execute command on state change
Pomo will execute the command specified in the array argument `onEvent` when the
state changes. The new state will be exported as an environment variable
`POMO_STATE` for this command. For example, to trigger a terminal bell when a
session complete, add the following to `config.json`
```
...
"onEvent": ["/bin/sh", "/path/to/script/my_script.sh"]
...
```
where the contents of `my_script.sh` are
```
#!/bin/sh
if [ "$POMO_STATE" == "COMPLETE" ] ; then
echo -e '\a'
fi
```
Possible state values are `RUNNING`, `PAUSED`, `BREAKING`, or `COMPLETE`.
## Integrations
By default pomo will setup a Unix socket and serve it's status there.

View File

@ -23,6 +23,7 @@ type Config struct {
DBPath string `json:"dbPath"`
SocketPath string `json:"socketPath"`
IconPath string `json:"iconPath"`
OnEvent []string `json:"onEvent"`
// Publish pushes updates to the configured
// SocketPath rather than listening for requests
Publish bool `json:"publish"`

View File

@ -2,6 +2,9 @@ package pomo
import (
"database/sql"
"fmt"
"os"
"os/exec"
"sync"
"time"
)
@ -21,6 +24,7 @@ type TaskRunner struct {
notifier Notifier
duration time.Duration
mu sync.Mutex
onEvent []string
}
func NewMockedTaskRunner(task *Task, store *Store, notifier Notifier) (*TaskRunner, error) {
@ -55,6 +59,7 @@ func NewTaskRunner(task *Task, config *Config) (*TaskRunner, error) {
toggle: make(chan bool),
notifier: NewXnotifier(config.IconPath),
duration: task.Duration,
onEvent: config.OnEvent,
}
return tr, nil
}
@ -75,6 +80,20 @@ func (t *TaskRunner) SetState(state State) {
t.state = state
}
// execute script command specified by `onEvent` on state change
func (t *TaskRunner) OnEvent() error {
app, args := t.onEvent[0], t.onEvent[1:len(t.onEvent)]
cmd := exec.Command(app, args...)
cmd.Env = append(os.Environ(),
fmt.Sprintf("POMO_STATE=%s", t.state),
)
err := cmd.Run()
if err != nil {
return err
}
return nil
}
func (t *TaskRunner) run() error {
for t.count < t.nPomodoros {
// Create a new pomodoro where we
@ -85,6 +104,8 @@ func (t *TaskRunner) run() error {
pomodoro.Start = time.Now()
// Set state to RUNNIN
t.SetState(RUNNING)
// Execute onEvent command
t.OnEvent()
// Create a new timer
timer := time.NewTimer(t.duration)
// Record our started time
@ -104,6 +125,8 @@ func (t *TaskRunner) run() error {
remaining := t.TimeRemaining()
// Change state to PAUSED
t.SetState(PAUSED)
// Execute onEvent command
t.OnEvent()
// Wait for the user to press [p]
<-t.pause
// Resume the timer with previous
@ -114,6 +137,8 @@ func (t *TaskRunner) run() error {
t.duration = remaining
// Restore state to RUNNING
t.SetState(RUNNING)
// Execute onEvent command
t.OnEvent()
goto loop
}
pomodoro.End = time.Now()
@ -128,6 +153,8 @@ func (t *TaskRunner) run() error {
break
}
t.SetState(BREAKING)
// Execute onEvent command
t.OnEvent()
t.notifier.Notify("Pomo", "It is time to take a break!")
// Reset the duration incase it
// was paused.
@ -138,6 +165,8 @@ func (t *TaskRunner) run() error {
}
t.notifier.Notify("Pomo", "Pomo session has completed!")
t.SetState(COMPLETE)
// Execute onEvent command
t.OnEvent()
return nil
}