Merge pull request #61 from sboysel/feature/exec-on-event
Execute command on state change
This commit is contained in:
commit
e6aa45152c
27
README.md
27
README.md
|
@ -65,6 +65,33 @@ Example:
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Execute command on state change
|
||||||
|
|
||||||
|
Pomo will execute an arbitrary command specified in the array argument `onEvent`
|
||||||
|
when the state changes. The first element of this array should be the
|
||||||
|
executable to run while the remaining elements are space delimited arguments.
|
||||||
|
The new state will be exported as an environment variable `POMO_STATE` for this
|
||||||
|
command. Possible state values are `RUNNING`, `PAUSED`, `BREAKING`, or
|
||||||
|
`COMPLETE`.
|
||||||
|
|
||||||
|
For example, to trigger a terminal bell when a session completes, add the
|
||||||
|
following to `config.json`:
|
||||||
|
```json
|
||||||
|
...
|
||||||
|
"onEvent": ["/bin/sh", "/path/to/script/my_script.sh"],
|
||||||
|
...
|
||||||
|
```
|
||||||
|
where the contents of `my_script.sh` are
|
||||||
|
```bash
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
if [ "$POMO_STATE" == "COMPLETE" ] ; then
|
||||||
|
echo -e '\a'
|
||||||
|
fi
|
||||||
|
```
|
||||||
|
|
||||||
|
See the `contrib` directory for user contributed scripts for use with `onEvent`.
|
||||||
|
|
||||||
## Integrations
|
## Integrations
|
||||||
|
|
||||||
By default pomo will setup a Unix socket and serve it's status there.
|
By default pomo will setup a Unix socket and serve it's status there.
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
echo -e '\e'
|
|
@ -0,0 +1,5 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
if [ "$POMO_STATE" == "BREAKING" ] ; then
|
||||||
|
swaynag -m "It's time to take a break!"
|
||||||
|
fi
|
|
@ -23,6 +23,7 @@ type Config struct {
|
||||||
DBPath string `json:"dbPath"`
|
DBPath string `json:"dbPath"`
|
||||||
SocketPath string `json:"socketPath"`
|
SocketPath string `json:"socketPath"`
|
||||||
IconPath string `json:"iconPath"`
|
IconPath string `json:"iconPath"`
|
||||||
|
OnEvent []string `json:"onEvent"`
|
||||||
// Publish pushes updates to the configured
|
// Publish pushes updates to the configured
|
||||||
// SocketPath rather than listening for requests
|
// SocketPath rather than listening for requests
|
||||||
Publish bool `json:"publish"`
|
Publish bool `json:"publish"`
|
||||||
|
|
|
@ -2,6 +2,9 @@ package pomo
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
@ -21,6 +24,7 @@ type TaskRunner struct {
|
||||||
notifier Notifier
|
notifier Notifier
|
||||||
duration time.Duration
|
duration time.Duration
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
|
onEvent []string
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewMockedTaskRunner(task *Task, store *Store, notifier Notifier) (*TaskRunner, error) {
|
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),
|
toggle: make(chan bool),
|
||||||
notifier: NewXnotifier(config.IconPath),
|
notifier: NewXnotifier(config.IconPath),
|
||||||
duration: task.Duration,
|
duration: task.Duration,
|
||||||
|
onEvent: config.OnEvent,
|
||||||
}
|
}
|
||||||
return tr, nil
|
return tr, nil
|
||||||
}
|
}
|
||||||
|
@ -73,6 +78,34 @@ func (t *TaskRunner) TimePauseDuration() time.Duration {
|
||||||
|
|
||||||
func (t *TaskRunner) SetState(state State) {
|
func (t *TaskRunner) SetState(state State) {
|
||||||
t.state = state
|
t.state = state
|
||||||
|
// execute onEvent command if variable is set
|
||||||
|
if t.onEvent != nil {
|
||||||
|
go t.runOnEvent()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// execute script command specified by `onEvent` on state change
|
||||||
|
func (t *TaskRunner) runOnEvent() error {
|
||||||
|
var cmd *exec.Cmd
|
||||||
|
// parse command arguments
|
||||||
|
numArgs := len(t.onEvent)
|
||||||
|
app := t.onEvent[0]
|
||||||
|
if numArgs > 1 {
|
||||||
|
args := t.onEvent[1:(numArgs + 1)]
|
||||||
|
cmd = exec.Command(app, args...)
|
||||||
|
} else {
|
||||||
|
cmd = exec.Command(app)
|
||||||
|
}
|
||||||
|
// set state in command environment
|
||||||
|
cmd.Env = append(os.Environ(),
|
||||||
|
fmt.Sprintf("POMO_STATE=%s", t.state),
|
||||||
|
)
|
||||||
|
// run command
|
||||||
|
err := cmd.Run()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TaskRunner) run() error {
|
func (t *TaskRunner) run() error {
|
||||||
|
|
Loading…
Reference in New Issue