Git Product home page Git Product logo

pod-babashka-fswatcher's Introduction

pod-babashka-fswatcher

A babashka pod for watching files.

Implemented using the Go fsnotify library.

Status

Experimental.

Usage

Load the pod:

(require '[babashka.pods :as pods])
(pods/load-pod 'org.babashka/fswatcher "0.0.5")

(require '[pod.babashka.fswatcher :as fw])

Watchers can be created with fw/watch:

(def watcher (fw/watch "src" (fn [event] (prn event))))

You can create multiple watchers that run concurrently, even on the same directory.

The watch function returns a value which can be passed to unwatch which stops and cleans up the watcher:

(fw/unwatch watcher)

See test/script.clj for an example test script.

Usage in bb.edn

In babashka 0.8.0 it is possible to specify pods in bb.edn:

{:pods {org.babashka/fswatcher {:version "0.0.5"}}
 :tasks {watch {:requires ([pod.babashka.fswatcher :as fw])
                :task (do (fw/watch "project.clj"
                                    (fn [event]
                                      (when (#{:write :write|chmod} (:type event))
                                        (println "hello!"))))
                          (deref (promise)))}}}

Watch recursively

By default watchers do not watch recursively. Pass {:recursive true} in the options map to enable it.

(fw/watch "src" (fn [event] (prn event)) {:recursive true})

Build

Requirements

  • Go 1.18+ should be installed.
  • Clone this repo.
  • Run go build -o pod-babashka-fswatcher main.go to compile the binary.

License

Copyright © 2020 Rahul De and Michiel Borkent

License: BSD 3-Clause

pod-babashka-fswatcher's People

Contributors

aiba avatar borkdude avatar fjsousa avatar lispyclouds avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

pod-babashka-fswatcher's Issues

Duplicate events on one file change in Windows 10

(pods/load-pod 'org.babashka/fswatcher "0.0.2")
(require '[pod.babashka.fswatcher :as fw])

(def count (atom 0))

(def watcher (fw/watch "some-file.txt"
                       (fn [event]
                         (do
                           (prn event)
                           (swap! count inc)))
                       {:delay-ms 250}))

When I modify the file then it prints twice and increments count from 0 to 2.

Add test

@lispyclouds The script in test/script.clj is now a proper runnable babashka test script. It returns a non-zero exit code when the compiled pod doesn't work correctly. Maybe we can hook this up as a test in CI and run it with babashka.

Duplicate events when :recursive true

By quickly looking into it, it seems to be an expected behaviour because the watchers are being added to the base directory and to the file itself.

There's dedup logic as an example in fsnotify

Should this test assert that there's only one event? https://github.com/babashka/pod-babashka-fswatcher/blob/main/test/script.clj#L38

Steps to reproduce

I have a single file bb.edn in my dir

{:paths ["src"]
 :pods {org.babashka/fswatcher {:version "0.0.3"}}
 :tasks
 { watch {:requires ([pod.babashka.fswatcher :as fw]
                     [babashka.fs :as fs])
                :task (do (fw/watch "." prn {:recursive true :delay-ms 500})
                          (deref (promise)))}}}

I start my watcher:

[fsousa@work fs-watch-issue]$ bb watch 
{:type :write, :path "./bb.edn"}
{:type :write, :path "bb.edn"}
{:type :write, :path "./bb.edn"}
{:type :write, :path "bb.edn"}

then just modify bb.edn with a new line.

Decide on LICENSE

I usually go with EPL-1 since that's what Clojure uses, but since this code doesn't have any Clojure core sources in it, we can choose whatever we want. Up to you @lispyclouds. I added a copyright statement in the README. We will have to add a LICENSE file.

Crashes on error message?

I'm getting this stacktrace from fswatcher:

#error {
 :cause "java.lang.String cannot be cast to clojure.lang.Associative"
 :via
 [{:type java.lang.ClassCastException
   :message "java.lang.String cannot be cast to clojure.lang.Associative"
   :at [clojure.lang.RT assoc "RT.java" 827]}]
 :trace
 [[clojure.lang.RT assoc "RT.java" 827]
  [clojure.core$assoc__5481 invokeStatic "core.clj" 193]
  [clojure.core$update invokeStatic "core.clj" 6231]
  [clojure.core$update invoke "core.clj" 6223]
  [sci.impl.vars.SciVar invoke "vars.cljc" 334]
  [sci.impl.analyzer$return_call$reify__9096 eval "analyzer.cljc" 1180]
  [sci.impl.analyzer$return_binding_call$reify__8967 eval "analyzer.cljc" 1098]
  [sci.impl.fns$fun$arity_1__7412 invoke "fns.cljc" 106]
  [babashka.pods.impl$processor invokeStatic "impl.clj" 227]
  [babashka.pods.sci$load_pod$fn__30772 invoke "sci.clj" 119]
  [sci.impl.vars$binding_conveyor_fn$fn__343 invoke "vars.cljc" 154]
  [clojure.core$binding_conveyor_fn$fn__5823 invoke "core.clj" 2047]
  [clojure.lang.AFn call "AFn.java" 18]
  [java.util.concurrent.FutureTask run "FutureTask.java" 264]
  [java.util.concurrent.ThreadPoolExecutor runWorker "ThreadPoolExecutor.java" 1128]
  [java.util.concurrent.ThreadPoolExecutor$Worker run "ThreadPoolExecutor.java" 628]
  [java.lang.Thread run "Thread.java" 829]
  [com.oracle.svm.core.thread.JavaThreads threadStartRoutine "JavaThreads.java" 597]

I think what's going on is that in the error cases, event is a string on this line:

(cb (update event :type keyword)))

And the call to update with a string argument causes the crash.

It seems like this is because in error cases, babashka.WriteInvokeResponse is being called with a json string rather than a Response struct:

babashka.WriteInvokeResponse(message, json)

babashka.WriteInvokeResponse(message, json)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.