Skip to content

Commit

Permalink
Add basic fs.watch implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
Rafflesiaceae committed Apr 27, 2024
1 parent 0ce836a commit d0f5195
Show file tree
Hide file tree
Showing 5 changed files with 146 additions and 2 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ See [./quicktest.nosh](./quicktest.nosh) for examples.
- [X] fs.remove
- [X] fs.touch
- [ ] fs.mktemp
- [X] fs.watch

- [ ] net.ping
- [ ] net.curl
2 changes: 2 additions & 0 deletions fs/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ var ModuleRead = starlark.NewBuiltin("fs.read", read)
var ModuleReaddir = starlark.NewBuiltin("fs.readdir", readdir)
var ModuleRemove = starlark.NewBuiltin("fs.remove", remove)
var ModuleTouch = starlark.NewBuiltin("fs.touch", touch)
var ModuleWatch = starlark.NewBuiltin("fs.watch", watch)
var ModuleWrite = starlark.NewBuiltin("fs.write", write)

var Module *starlarkstruct.Module
Expand Down Expand Up @@ -60,6 +61,7 @@ func init() {
"split_list": starlark.NewBuiltin("fs.split_list", splitList),
"to_slash": starlark.NewBuiltin("fs.to_slash", toSlash),
"touch": ModuleTouch,
"watch": ModuleWatch,
"write": ModuleWrite,
},
}
Expand Down
134 changes: 134 additions & 0 deletions fs/watch.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
package fs

import (
"fmt"
"log"

"go.starlark.net/starlark"
strlk "go.starlark.net/starlark"

"github.com/fsnotify/fsnotify"
)

// {{{1 WatchEvent
type WatchEvent struct {
/**
One of:
CHMOD
CREATE
REMOVE
*/
Operation string
FileEntry
}

var (
_ strlk.Value = &WatchEvent{}
_ strlk.HasAttrs = &WatchEvent{}
)

func (we *WatchEvent) Freeze() { /* @TODO */ }
func (we *WatchEvent) Hash() (uint32, error) { /* @TODO */ return 0, nil }
func (we *WatchEvent) Truth() strlk.Bool { return true }
func (we *WatchEvent) Type() string { return "WatchEvent" }

// func (we *WatchEvent) String() string { return we.AbsPath }
func (we *WatchEvent) String() string { return we.Operation + "\t" + we.AbsPath }

func (we *WatchEvent) Attr(name string) (result strlk.Value, err error) {
switch name {
case "abspath":
return strlk.String(we.AbsPath), nil
case "basename":
return strlk.String(we.BaseName), nil
case "dir":
return strlk.String(we.Dir), nil
case "ext":
return strlk.String(we.Ext), nil
case "name":
return strlk.String(we.Name), nil
case "path":
return strlk.String(we.Path), nil

case "operation":
return strlk.String(we.Operation), nil
}
return starlark.None, fmt.Errorf("Unknown attr: %s", name)
}

func (we *WatchEvent) AttrNames() []string {
return []string{
"abspath",
"basename",
"dir",
"ext",
"name",
"path",

"operation",
}
}

func watch(thread *starlark.Thread, fn *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
var (
path string
callback starlark.Callable
)

if err := starlark.UnpackArgs("watch", args, kwargs, "path", &path, "callback", &callback); err != nil {
return nil, err
}

// @TODO improve, current implementation is very basic
// @TODO add non-blocking option
// @TODO improve error handling (use error channel, don't use 'panic')
{
// Create new watcher.
watcher, err := fsnotify.NewWatcher()
if err != nil {
return nil, err
}
defer watcher.Close()

// Start listening for events.
go func() {
for {
select {
case event, ok := <-watcher.Events:
if !ok {
return
}

// populate starlark event
strlkEvent := &WatchEvent{
Operation: event.Op.String(),
}
err = strlkEvent.FileEntry.Init(event.Name)
if err != nil {
panic(err)
}

_, err = starlark.Call(thread, callback, starlark.Tuple{strlkEvent}, nil)
if err != nil {
panic(err)
}

case err, ok := <-watcher.Errors:
if !ok {
return
}
log.Println("ERROR", err)
}
}
}()

err = watcher.Add(path)
if err != nil {
return nil, err
}

<-make(chan struct{}) // @XXX
}

return starlark.None, nil
}
7 changes: 5 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ module github.com/Rafflesiaceae/nosh

go 1.22.1

require go.starlark.net v0.0.0-20240314022150-ee8ed142361c
require (
github.com/fsnotify/fsnotify v1.7.0
go.starlark.net v0.0.0-20240314022150-ee8ed142361c
)

require golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 // indirect
require golang.org/x/sys v0.4.0 // indirect
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
go.starlark.net v0.0.0-20240314022150-ee8ed142361c h1:roAjH18hZcwI4hHStHbkXjF5b7UUyZ/0SG3hXNN1SjA=
go.starlark.net v0.0.0-20240314022150-ee8ed142361c/go.mod h1:YKMCv9b1WrfWmeqdV5MAuEHWsu5iC+fe6kYl2sQjdI8=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 h1:0A+M6Uqn+Eje4kHMK80dtF3JCXC4ykBgQG4Fe06QRhQ=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18=
golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=

0 comments on commit d0f5195

Please sign in to comment.