appwatchertools

package module
v0.0.0-...-6bfb68b Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 18, 2021 License: MIT Imports: 12 Imported by: 0

README

appwatchertools

@todo add run forever to buildscript

Utility functions for setting up an application watcher.

Get started

go get github.com/mdev5000/appwatchertools

Example

watcher/watcher.go

package main

import (
	"github.com/mdev5000/appwatchertools"
	"context"
	"fmt"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
)

func ensureOk(err error) {
	if err != nil {
		panic(err)
	}
}

type runner struct {
	appWatcher *appwatchertools.AppWatcher
}

func main() {
	r := &runner{
		appWatcher: appwatchertools.NewAppWatcher(),
	}

	wd, err := os.Getwd()
	ensureOk(err)
	r.appWatcher.Dir = wd

	// Only watch application files.
	r.appWatcher.FileFilter = func(path string) (bool, error) {
		return r.isApplicationPath(wd, path), nil
	}

	r.appWatcher.OnChangeFn = r.onChange

	// OnChange will rebuild the application and remake the exe ./app, after that
	// we can run the application.
	r.appWatcher.CommandFn = func() *exec.Cmd {
		// Usually you would run the compiled application here.
		// return exec.Command("./app")
		return exec.Command("echo", "running app")
	}

	// Run the watcher.
	ctx := context.Background()
	ensureOk(r.appWatcher.Run(ctx))
}

// When a file changes run build and main applications and is there's no errors
// start the application.
func (r *runner) onChange(files []string, isInit bool) bool {
	fmt.Println("building things")

	// Usually you could build the app here:
	//
	//if err := r.appWatcher.RunCommand("go", "build", "-o", "app", "main/main.go"); err != nil {
	//	r.appWatcher.ExeLogger.Error(err)
	//	return false
	//}

	if err := r.appWatcher.RunCommand("echo", "building"); err != nil {
		r.appWatcher.ExeLogger.Error(err)
		return false
	}
	return true
}

// Limit what files and directories are watched
// In this case anything in:
//	[rootdir]/main/
//	[rootdir]/app/
func (r *runner) isApplicationPath(dir string, path string) bool {
	return strings.HasPrefix(path, filepath.Join(dir, "main")) ||
		strings.HasPrefix(path, filepath.Join(dir, "app"))
}

You can then run the watcher with:

go run watcher/watcher.go

Development

Initialize the development environment with.

make dev-init

You can test with usual go test.

Finally you can also run example2.

go run examples/example2/watcher.go

After starting the watcher add files to /testdata/tmp/example2_files and change them and the watcher should update.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func WatchDir

func WatchDir(cfg *WatchConfig, ctx context.Context, events chan<- fsnotify.Event) error

Types

type AppWatcher

type AppWatcher struct {
	Dir        string
	Debounce   time.Duration
	ExeLogger  ExeLogger
	FileFilter WatchFileFilter
	OnChangeFn OnChange
	CommandFn  MakeCommandFn
}

func NewAppWatcher

func NewAppWatcher() *AppWatcher

func (*AppWatcher) Run

func (a *AppWatcher) Run(ctx context.Context) error

func (*AppWatcher) RunCommand

func (a *AppWatcher) RunCommand(cmd string, args ...string) error

Simple utility function for running a command.

type DefaultLogger

type DefaultLogger struct {
}

func (DefaultLogger) Error

func (e DefaultLogger) Error(err error)

func (DefaultLogger) Success

func (e DefaultLogger) Success(msg string, args ...interface{})

type ExeLogger

type ExeLogger interface {
	Success(msg string, args ...interface{})
	Error(error)
}

type ExeRefresher

type ExeRefresher struct {
	Stdin  io.Reader
	Stdout io.Writer
	Stderr io.Writer
	//ID        string
	Logger    ExeLogger
	Restart   chan bool
	CommandFn MakeCommandFn
}

func NewExeRefresher

func NewExeRefresher() *ExeRefresher

func (*ExeRefresher) Run

func (r *ExeRefresher) Run(ctx context.Context)

type MakeCommandFn

type MakeCommandFn = func() *exec.Cmd

type OnChange

type OnChange = func(fileChanges []string, isInit bool) bool

type OnChangeFn

type OnChangeFn = func(path []string) error

type OnFileChange

type OnFileChange = func(path []string) error

type WatchConfig

type WatchConfig struct {
	Dir      string
	Debounce time.Duration

	// Returns true if file should be watched.
	Filter WatchFileFilter

	OnChange OnChangeFn
	// contains filtered or unexported fields
}

func NewWatchConfig

func NewWatchConfig() *WatchConfig

type WatchFileFilter

type WatchFileFilter = func(path string) (bool, error)

type Watcher

type Watcher = WatchConfig

func NewWatcher

func NewWatcher() *Watcher

func (*Watcher) WatchForChanges

func (w *Watcher) WatchForChanges(ctx context.Context) error

Directories

Path Synopsis
examples

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL