streamly-fsnotify: Folder watching as a Streamly stream.

[ bsd3, library, streamly, system ] [ Propose Tags ]

Provides Streamly streams for both single-level and recursive folder watching. Also contains a principled and compositional system for filtering file system events.

[Skip to Readme]


[Index] [Quick Jump]


Note: This package has metadata revisions in the cabal description newer than included in the tarball. To unpack the package including the revisions, use 'cabal get'.

Maintainer's Corner

For package maintainers and hackage trustees


Versions [RSS],,,,
Change log
Dependencies base (>=4.9 && <5), filepath (>= && <1.5), fsnotify (>= && <0.4), semirings (>=0.5.2 && <0.7), streamly (>=0.7.0 && <0.9), text (>= && <1.3), time (>=1.6 && <1.13) [details]
License BSD-3-Clause
Author Koz Ross, George Thomas
Maintainer George Thomas
Revised Revision 2 made by GeorgeThomas at 2021-06-30T21:10:48Z
Category Streamly, System
Home page
Uploaded by GeorgeThomas at 2020-05-27T10:42:36Z
Distributions NixOS:
Downloads 1132 total (8 in the last 30 days)
Rating 2.0 (votes: 1) [estimated by Bayesian average]
Your Rating
  • λ
  • λ
  • λ
Status Docs uploaded by user
Build status unknown [no reports yet]

Readme for streamly-fsnotify-

[back to package description]

What's the deal with this library?

streamly is an undoubtedly awesome library - fast, flexible, and well-documented. File system watching is a natural fit for a streaming library, and this is exactly what streamly-fsnotify provides you.

As an example, here is a program which watches /home/koz/c-project/ and any of its subdirectories for added or modified C source files (which we take to be anything with a .c extension). This program then writes that the event occurred, to what file, and when, forever.

{-# LANGUAGE LambdaCase #-}

import System.FilePath ((</>))
import Streamly.FSNotify (EventPredicate, hasExtension, isDirectory, invert, isDeletion, conj, watchTree)
import qualified Streamly.Prelude as SP

-- conj -> both must be true
-- invert -> true when the argument would be false and vice versa
isCSourceFile :: EventPredicate
isCSourceFile = hasExtension "c" `conj` invert isDirectory

notDeletion :: EventPredicate
notDeletion = invert isDeletion

srcPath :: FilePath
srcPath = "home" </> "koz" </> "c-project"

-- first value given by watchTree stops the watcher
-- we don't use it here, but if you want to, just call it
main :: IO ()
main = do
    (_, stream) <- watchTree srcPath $ isCSourceFile `conj` notDeletion
    SP.drain . SP.mapM go $ stream
    go = \case
        Added p t _ -> putStrLn $ "Created: " ++ show p ++ " at " ++ show t
        Modified p t _ -> putStrLn $ "Modified: " ++ show p ++ " at " ++ show t
        _ -> pure ()

That seems pretty cool! What kind of features can I expect?

  • Cross-platform - should work anywhere both streamly and fsnotify do.
  • Efficient (event-driven, so won't shred your CPU or load your RAM).
  • Able to do one-level and recursive watching.
  • Compositional and principled treatment of event filtering predicates.
  • Extensive set of filtering predicates, so you don't have to see events you don't care about!

Sounds good? Can I use it?

We've test-built this library for GHCs 8.6.5 through 8.10.1 on GNU/Linux. In theory, streamly-fsnotify should work everywhere both streamly and fsnotify will, which includes other OSes (such as Windows). However, we haven't tried it ourselves - let us know if you do!