You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
172 lines
3.6 KiB
172 lines
3.6 KiB
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"os/exec"
|
|
"log"
|
|
"io"
|
|
"os"
|
|
"time"
|
|
"io/fs"
|
|
"path/filepath"
|
|
"errors"
|
|
"lcthw.dev/go/ttarpit/config"
|
|
"github.com/fsnotify/fsnotify"
|
|
"bufio"
|
|
)
|
|
|
|
func LaunchLogger(in io.Reader, out io.Writer, err error) {
|
|
if err != nil { log.Fatal(err) }
|
|
|
|
go func() {
|
|
scan := bufio.NewScanner(in)
|
|
|
|
for scan.Scan() {
|
|
for _, reg := range config.Settings.TriggerRegex {
|
|
line := scan.Text()
|
|
|
|
matches := reg.FindStringSubmatch(line)
|
|
if len(matches) > 0 {
|
|
file, line, col, err_type, text := matches[1], matches[2], matches[3], matches[4], matches[5]
|
|
fmt.Printf("!!!!!!!!!!!!!! file=%s, line=%s, col=%s, type=%s, text=%s\n",
|
|
file, line, col, err_type, text)
|
|
}
|
|
}
|
|
}
|
|
}()
|
|
}
|
|
|
|
func LaunchProcess(proc *config.Process) {
|
|
proc.ExecCmd = exec.Command(proc.Command, proc.Args...)
|
|
if errors.Is(proc.ExecCmd.Err, exec.ErrDot) {
|
|
proc.ExecCmd.Err = nil
|
|
}
|
|
|
|
fmt.Println("STARTING", proc.Command)
|
|
|
|
stderr, err := proc.ExecCmd.StderrPipe();
|
|
LaunchLogger(stderr, os.Stdout, err)
|
|
|
|
stdout, err := proc.ExecCmd.StdoutPipe();
|
|
LaunchLogger(stdout, os.Stdout, err)
|
|
|
|
err = proc.ExecCmd.Start()
|
|
if err != nil {
|
|
log.Fatalf("FAIL %s %s err=%v", proc.Command, proc.Args, err)
|
|
}
|
|
|
|
fmt.Println("WAITING for", proc.Command)
|
|
|
|
fmt.Println("SENDING READY on channel")
|
|
|
|
proc.ExecCmd.Wait()
|
|
fmt.Println("PROCESS", proc.Command, "EXITED")
|
|
}
|
|
|
|
func MatchesPath(fp string) bool {
|
|
fp = filepath.ToSlash(fp)
|
|
|
|
for _, reg := range config.Settings.IncludeRegex {
|
|
matches := reg.MatchString(fp)
|
|
|
|
if matches {
|
|
return true
|
|
}
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
func RunBuild() {
|
|
if !config.Settings.BuildRunning {
|
|
config.Settings.BuildRunning = true
|
|
defer func(){config.Settings.BuildRunning = false}()
|
|
|
|
fmt.Println("CONFIG:", config.Settings.ConfigPath)
|
|
fmt.Println("COMMANDs:", config.Settings.Processes)
|
|
|
|
for name, proc := range config.Settings.Processes {
|
|
fmt.Println("PROCESS:", name)
|
|
|
|
LaunchProcess(&proc)
|
|
fmt.Println("=================== PROCESS EXIT")
|
|
}
|
|
|
|
time.Sleep(1000 * time.Millisecond)
|
|
} else {
|
|
fmt.Println("!!!! BUILD SKIP, already running")
|
|
}
|
|
}
|
|
|
|
func AddWatchDir(watcher *fsnotify.Watcher, name string) error {
|
|
return filepath.WalkDir(name,
|
|
func(path string, d fs.DirEntry, err error) error {
|
|
if err != nil {
|
|
log.Printf("WATCH ERROR! walking=%s path=%s: err=%v", name, path, err)
|
|
return err
|
|
}
|
|
|
|
if d.IsDir() {
|
|
log.Println("WATCHING: ", path)
|
|
err = watcher.Add(path)
|
|
if err != nil {
|
|
log.Printf("failed to watch %s", path)
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
})
|
|
}
|
|
|
|
func WatchDir() {
|
|
watcher, err := fsnotify.NewWatcher()
|
|
if err != nil {
|
|
log.Fatal("Failed to start fsnotify", err)
|
|
}
|
|
defer watcher.Close()
|
|
|
|
go func() {
|
|
for {
|
|
select {
|
|
case event, ok := <-watcher.Events:
|
|
if !ok {
|
|
return
|
|
}
|
|
|
|
if event.Has(fsnotify.Create) {
|
|
log.Println("---> CREATE", event.Name)
|
|
AddWatchDir(watcher, event.Name)
|
|
} else if event.Has(fsnotify.Write) {
|
|
// check if match then do thing
|
|
if MatchesPath(event.Name) {
|
|
go RunBuild()
|
|
}
|
|
} else {
|
|
log.Println("event:", event)
|
|
}
|
|
case err, ok := <-watcher.Errors:
|
|
if !ok {
|
|
return
|
|
}
|
|
log.Println("error: ", err)
|
|
}
|
|
}
|
|
}()
|
|
|
|
err = AddWatchDir(watcher, ".")
|
|
|
|
if err != nil {
|
|
log.Fatal(err, "Failed to watch .")
|
|
}
|
|
|
|
<-make(chan struct{})
|
|
}
|
|
|
|
|
|
func main() {
|
|
config.Load()
|
|
|
|
fmt.Println("WAITING....")
|
|
WatchDir()
|
|
}
|
|
|