Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion cmd/modd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,15 @@ import (

"github.com/cortesi/modd"
"github.com/cortesi/modd/notify"
"github.com/cortesi/modd/report"
"github.com/cortesi/termlog"
"gopkg.in/alecthomas/kingpin.v2"
"mvdan.cc/sh/v3/interp"
"mvdan.cc/sh/v3/syntax"
)

const modfile = "./modd.conf"
const reportFile = ".modd_report"

var file = kingpin.Flag(
"file",
Expand All @@ -41,6 +43,10 @@ var doNotify = kingpin.Flag("notify", "Send stderr to system notification if com
Short('n').
Bool()

var doReport = kingpin.Flag("report", "Report last prep status to file").
Short('r').
Bool()

var prep = kingpin.Flag("prep", "Run prep commands and exit").
Short('p').
Bool()
Expand Down Expand Up @@ -109,7 +115,15 @@ func main() {
notifiers = append(notifiers, &notify.BeepNotifier{})
}

mr, err := modd.NewModRunner(*file, log, notifiers, !(*noconf))
reporters := []report.Reporter{}
if *doReport {
r := report.FileReporter{
Filename: reportFile,
}
reporters = append(reporters, r)
}

mr, err := modd.NewModRunner(*file, log, notifiers, reporters, !(*noconf))
if err != nil {
log.Shout("%s", err)
return
Expand Down
2 changes: 2 additions & 0 deletions conf/conf.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ type Block struct {

Daemons []Daemon
Preps []Prep

Status int
}

func (b *Block) addPrep(command string, options []string) error {
Expand Down
37 changes: 31 additions & 6 deletions modd.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (

"github.com/cortesi/modd/conf"
"github.com/cortesi/modd/notify"
"github.com/cortesi/modd/report"
"github.com/cortesi/modd/shell"
"github.com/cortesi/moddwatch"
"github.com/cortesi/termlog"
Expand Down Expand Up @@ -58,15 +59,17 @@ type ModRunner struct {
ConfPath string
ConfReload bool
Notifiers []notify.Notifier
Reporters []report.Reporter
}

// NewModRunner constructs a new ModRunner
func NewModRunner(confPath string, log termlog.TermLog, notifiers []notify.Notifier, confreload bool) (*ModRunner, error) {
func NewModRunner(confPath string, log termlog.TermLog, notifiers []notify.Notifier, reporters []report.Reporter, confreload bool) (*ModRunner, error) {
mr := &ModRunner{
Log: log,
ConfPath: confPath,
ConfReload: confreload,
Notifiers: notifiers,
Reporters: reporters,
}
err := mr.ReadConfig()
if err != nil {
Expand Down Expand Up @@ -106,12 +109,12 @@ func (mr *ModRunner) PrepOnly(initial bool) error {
return nil
}

func (mr *ModRunner) runBlock(b conf.Block, mod *moddwatch.Mod, dpen *DaemonPen) {
func (mr *ModRunner) runBlock(b conf.Block, mod *moddwatch.Mod, dpen *DaemonPen) error {
if b.InDir != "" {
currentDir, err := os.Getwd()
if err != nil {
mr.Log.Shout("Error getting current working directory: %s", err)
return
return err
}
err = os.Chdir(b.InDir)
if err != nil {
Expand All @@ -120,7 +123,7 @@ func (mr *ModRunner) runBlock(b conf.Block, mod *moddwatch.Mod, dpen *DaemonPen)
b.InDir,
err,
)
return
return err
}
defer func() {
err := os.Chdir(currentDir)
Expand All @@ -140,9 +143,10 @@ func (mr *ModRunner) runBlock(b conf.Block, mod *moddwatch.Mod, dpen *DaemonPen)
if _, ok := err.(ProcError); !ok {
mr.Log.Shout("Error running prep: %s", err)
}
return
return err
}
dpen.Restart()
return nil
}

func (mr *ModRunner) trigger(root string, mod *moddwatch.Mod, dworld *DaemonWorld) {
Expand All @@ -159,7 +163,28 @@ func (mr *ModRunner) trigger(root string, mod *moddwatch.Mod, dworld *DaemonWorl
continue
}
}
mr.runBlock(b, lmod, dworld.DaemonPens[i])

err := mr.runBlock(b, lmod, dworld.DaemonPens[i])

if err != nil {
mr.Config.Blocks[i].Status = 1
} else {
mr.Config.Blocks[i].Status = 0
}
}

// Compute overall status: != 0 if any block has Status != 0, otherwise 0.
status := 0

for _, b := range mr.Config.Blocks {
if status == 0 {
status = b.Status
}
}

// Report the overall status to all reporters.
for _, r := range mr.Reporters {
r.Report(time.Now(), status)
}
}

Expand Down
38 changes: 38 additions & 0 deletions report/reporter.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package report

import (
"fmt"
"os"
"time"
)

// Reporter publishes status updates.
type Reporter interface {
Report(timestamp time.Time, status int)
}

// FileReporter writes status updates to a file.
type FileReporter struct {
Filename string
}

// Report implements the Reporter interface.
func (fs FileReporter) Report(timestamp time.Time, status int) {
ts := time.Now().UTC().Format(time.RFC3339)
msg := fmt.Sprintf("%s,%d\n", ts, status)

// Open for write, create if missing, truncate to zero length.
f, err := os.OpenFile(fs.Filename, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0o644)
if err != nil {
return
}
defer f.Close()

if _, err := f.Write([]byte(msg)); err != nil {
return
}

if err := f.Sync(); err != nil {
return
}
}