Flier
Linux file-system helpers for Elixir, implemented as Rust NIFs:
Flier.Inotify— watch a directory for events (create, modify, delete, move, open, close, access, attribute changes) viainotify, as messages or as aStream.Flier.Entries— lazily stream the entries of a directory, flat or recursively, with their file type.
Flier is Linux-only. Precompiled NIFs are provided for x86_64, aarch64, 32-bit ARM (gnueabihf) and riscv64 glibc targets, so no Rust toolchain is needed.
Installation
def deps do
[
{:flier, "~> 0.6.0"}
]
end
To build the NIFs from source instead (for example on musl), see
"Building from source" in the Flier module docs.
Watching a directory
Messages are tagged with the watcher's ref, so several watchers can share
a process:
{:ok, %Flier.Inotify.Watcher{ref: ref} = watcher} =
Flier.Inotify.start_watcher("/tmp", [:create, :delete])
receive do
{:inotify_event, ^ref, %Flier.Inotify.Event{name: name, masks: masks}} ->
IO.puts("#{name}: #{inspect(masks)}")
end
:stopped = Flier.Inotify.stop_watcher(watcher)
Or as a stream, which starts and stops the watcher for you:
"/tmp"
|> Flier.Inotify.stream([:close_write])
|> Enum.each(fn event -> IO.puts("#{event.name}: #{inspect(event.masks)}") end)
The :moved_from and :moved_to events of a rename carry the same
:cookie, so the two halves can be paired up.
Errors are POSIX error atoms, as with File:
{:error, :enoent} = Flier.Inotify.start_watcher("/does/not/exist", :all)
Listing a directory
"/tmp"
|> Flier.Entries.stream()
|> Enum.each(fn entry -> IO.puts("#{entry.name} is a #{entry.type}") end)
Recursively, with an optional depth limit and symlink following:
root = "/home/user/projects"
root
|> Flier.Entries.stream(recursive: true, max_depth: 3)
|> Stream.filter(&(&1.type == :file))
|> Enum.map(&Path.join([root, &1.path, &1.name]))
If the root directory cannot be read, enumerating the stream raises a
File.Error. Unreadable subdirectories are skipped, unless
on_error: :raise is given.
Documentation
Full documentation is at https://hexdocs.pm/flier.