Skip to content

Commit

Permalink
fc
Browse files Browse the repository at this point in the history
  • Loading branch information
kamalshkeir committed Nov 18, 2022
0 parents commit 172b080
Show file tree
Hide file tree
Showing 12 changed files with 201 additions and 0 deletions.
13 changes: 13 additions & 0 deletions Readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
### Watcher or Auto-reloader

### install
```shell
go install github.com/kamalshkeir/kwatch/cmd/kwatch
```
or get the binary from Releases

### Then you can run:
```shell
kwatch --root ${PWD} (will watch all files at root)
kwatch --root ${PWD} --watch assets/templates,assets/static (will watch only '${PWD}/assets/templates' and '${PWD}/assets/static' folders)
```
Binary file added binaries/katcher_windows_32bit.exe
Binary file not shown.
Binary file added binaries/kwatch_ios_amd64
Binary file not shown.
Binary file added binaries/kwatch_ios_arm64
Binary file not shown.
Binary file added binaries/kwatch_linux_amd_32bit
Binary file not shown.
Binary file added binaries/kwatch_linux_amd_64bit
Binary file not shown.
Binary file added binaries/kwatch_linux_arm_64bit
Binary file not shown.
Binary file added binaries/kwatch_windows_64bit.exe
Binary file not shown.
23 changes: 23 additions & 0 deletions cmd/kwatch/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package main

import (
"flag"
"strings"
"time"

"github.com/kamalshkeir/klog"
"github.com/kamalshkeir/kwatch"
)

func main() {
root := flag.String("root", "", "root is fullPath to the project")
watch := flag.String("watch", "", "directory to watch inside root,if empty, will take all files and dirs inside root")
every := flag.Int("every", 313, "time in milliseconds")
flag.Parse()
if root == nil || *root == "" {
klog.Printfs("rderror: root tag not specified")
return
}
sp := strings.Split(*watch, ",")
kwatch.Watch(time.Duration(*every)*time.Millisecond, *root, sp...)
}
5 changes: 5 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module github.com/kamalshkeir/kwatch

go 1.19

require github.com/kamalshkeir/klog v1.0.0
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
github.com/kamalshkeir/klog v1.0.0 h1:xZbYuYlDsEG5gfHPGNVms7wQmUFJCV0Uo2pwwaJBbws=
github.com/kamalshkeir/klog v1.0.0/go.mod h1:Plp8wNXIbDTSgJmVOF/GiUftKihGqL6jvRAXPclbmV8=
158 changes: 158 additions & 0 deletions kwatch.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
package kwatch

import (
"fmt"
"os"
"os/exec"
"path/filepath"
"runtime"
"strings"
"time"

"github.com/kamalshkeir/klog"
)

func changesDetected(since time.Time, root string, dirs ...string) bool {
var changed bool
var err error
if len(dirs) == 0 {
err = filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if info.IsDir() {
return nil
}
if info.ModTime().After(since) {
changed = true
}
return nil
})
} else {
for _, d := range dirs {
err = filepath.Walk(root+"/"+d, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if info.IsDir() {
return nil
}
if info.ModTime().After(since) {
changed = true
}
return nil
})
}
}
if err != nil {
return false
}
return changed
}

type BuildFunc func() error

func ExecCommand(command string, args ...string) BuildFunc {
return func() error {
cmd := exec.Command(command, args...)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
err := cmd.Run()
if err != nil {
return fmt.Errorf("error building: \"%s %s\": %w", command, strings.Join(args, " "), err)
}
return nil
}
}

type LaunchFunc func() (stop func(), err error)

func LaunchCommand(command string, args ...string) LaunchFunc {
return func() (func(), error) {
cmd := exec.Command(command, args...)
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
err := cmd.Start()
if err != nil {
return nil, fmt.Errorf("error LaunchCommand: \"%s %s\": %w", command, strings.Join(args, " "), err)
}
return func() {
cmd.Process.Kill()
}, nil
}
}

func Start(before []BuildFunc, run LaunchFunc, after []BuildFunc) (func(), error) {
for _, fn := range before {
err := fn()
if err != nil {
return nil, err
}
}
stop, err := run()
if err != nil {
return nil, err
}
for _, fn := range after {
err := fn()
if err != nil {
stop()
return nil, err
}
}
return stop, nil
}

func Watch(every time.Duration, root string, dirs ...string) {
if every == 0 {
every = 500 * time.Millisecond
}
root = filepath.ToSlash(root)

ssp := strings.Split(root, "/")
projName := ssp[len(ssp)-1]
if projName == "" {
projName = ssp[len(ssp)-2]
if projName == "" {
klog.Printf("rd%s is empty",projName)
return
}
}
if runtime.GOOS == "windows" {
projName += ".exe"
}
var stop func()
var err error
var lastScan time.Time

if len(dirs) > 0 {
for _, d := range dirs {
klog.Printfs("grwatching %s", root+"/"+d)
}
} else {
klog.Printfs("grwatching %s", root)
}

for {
if !changesDetected(lastScan, root, dirs...) {
time.Sleep(every)
continue
}

if stop != nil {
klog.Printfs("ylRestarting...")
stop()
}
stop, err = Start(
[]BuildFunc{ExecCommand("go", "install", root)},
LaunchCommand(projName),
nil,
)
if err != nil {
klog.Printfs("error katcher:", err)
}
lastScan = time.Now()
time.Sleep(every)
}
}

0 comments on commit 172b080

Please sign in to comment.