diff options
| author | Raymaekers Luca <raymaekers.luca@gmail.com> | 2024-10-10 19:21:30 +0200 | 
|---|---|---|
| committer | Raymaekers Luca <raymaekers.luca@gmail.com> | 2024-10-10 19:21:30 +0200 | 
| commit | d6021aaad84068c01b4e53f161d07f57b9357f43 (patch) | |
| tree | e373b7e12d5c604dc773b0843a68daed08ad7ad8 | |
Initial commit
| -rw-r--r-- | LICENSE | 19 | ||||
| -rw-r--r-- | go.mod | 7 | ||||
| -rw-r--r-- | go.sum | 4 | ||||
| -rw-r--r-- | main.go | 158 | 
4 files changed, 188 insertions, 0 deletions
| @@ -0,0 +1,19 @@ +zlib License + +Copyright (C) 2024 Luca Raymaekers + +This software is provided 'as-is', without any express or implied +warranty.  In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not +   claim that you wrote the original software. If you use this software +   in a product, an acknowledgment in the product documentation would be +   appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be +   misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. @@ -0,0 +1,7 @@ +module wbr + +go 1.23.2 + +require github.com/fsnotify/fsnotify v1.7.0 + +require golang.org/x/sys v0.4.0 // indirect @@ -0,0 +1,4 @@ +github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= +github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= +golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18= +golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -0,0 +1,158 @@ +// [PROGRAM] will run a build command and a run command on file system changes.  This is so you can +// build&run on save. +// You specify a build command and run command as flags and optionally you can filter by extension. + +package main + +import ( +	"flag" +	"fmt" +	"os" +	"os/exec" +	"strings" + +	"github.com/fsnotify/fsnotify" +) + +// Colors in escape sequences +var ( +	Reset    = "\033[0m" +	BoldCyan = "\033[36m" +	// Red     = "\033[31m" +	// Green   = "\033[32m" +	// Yellow  = "\033[33m" +	// Blue = "\033[34m" +	// Magenta = "\033[35m" +	// Cyan = "\033[36m" +	// Gray    = "\033[37m" +	// White   = "\033[97m" +) + +var ( +	// Path in which to look for commands +	Path string +	// Command run for building +	BuildCommand []string +	// Command run after build +	RunCommand []string +	// Command will only run on files that have the Ext extension +	Ext string +) + +func CompileRun(fileName string) { +	if !strings.HasSuffix(fileName, Ext) { +		return +	} + +	// Build the program, exit if return if there was an error +	{ +		var buildCmd *exec.Cmd +		if len(BuildCommand) > 1 { +			buildCmd = exec.Command(BuildCommand[0], append(BuildCommand[1:], fileName)...) +		} else { +			buildCmd = exec.Command(BuildCommand[0], fileName) +		} +		// run the build command +		out, err := buildCmd.CombinedOutput() + +		if len(BuildCommand) > 1 { +			fmt.Printf("\n[%s%s %s%s]\n", BoldCyan, BuildCommand[0], strings.Join(append(BuildCommand[1:], fileName), " "), Reset) +		} else { +			fmt.Printf("[%s%s %s %s%s]\n", BoldCyan, BuildCommand[0], BuildCommand, fileName, Reset) +		} + +		if len(out) > 0 { +			fmt.Printf("%s", out) +		} + +		if err != nil { +			if _, ok := err.(*exec.ExitError); ok { +				return +			} else if !ok { +				panic(err) +			} +		} +	} + +	// There was no error in the build so we can execute the run command +	{ +		var runCmd *exec.Cmd +		if len(RunCommand) > 1 { +			runCmd = exec.Command(RunCommand[0], RunCommand[1:]...) +		} else { +			runCmd = exec.Command(RunCommand[0]) +		} + +		out, err := runCmd.CombinedOutput() +		if len(RunCommand) > 1 { +			fmt.Printf("[%s%s %s%s]\n", BoldCyan, RunCommand[0], strings.Join(append(RunCommand[1:]), " "), Reset) +		} else { +			fmt.Printf("[%s%s%s]\n", BoldCyan, RunCommand[0], Reset) + +		} +		if len(out) > 0 { +			fmt.Printf("%s", out) +		} + +		if err != nil { +			if _, ok := err.(*exec.ExitError); ok { +				return +			} else if !ok { +				panic(err) +			} +		} +	} + +} + +func main() { +	watcher, err := fsnotify.NewWatcher() +	if err != nil { +		panic(err) +	} +	defer watcher.Close() + +	bc := flag.String("b", "", "Command to run for building") +	rc := flag.String("r", "", "Command for running after build") +	e := flag.String("e", "", "Filter watched files by suffix") +	p := flag.String("p", ".", "Path to watch for files") +	flag.Parse() + +	if *bc == "" { +		fmt.Println("flag is required: -b") +		os.Exit(1) +	} + +	BuildCommand = strings.Split(*bc, " ") +	RunCommand = strings.Split(*rc, " ") +	Ext = *e +	Path = *p + +	fmt.Printf("[%swatching '%s'%s]", BoldCyan, Path, Reset) + +	go func() { +		for { +			select { +			case event, ok := <-watcher.Events: +				if !ok { +					return +				} +				if event.Has(fsnotify.Write) { +					CompileRun(event.Name) +				} +			case err, ok := <-watcher.Errors: +				if !ok { +					return +				} +				fmt.Println("error:", err) +			} +		} +	}() + +	err = watcher.Add(Path) +	if err != nil { +		panic(err) +	} + +	<-make(chan struct{}) +} | 
