ward.fs
- Existence and type checks
- Path utilities
- Directory listing and globbing
- Directories and removal
- Permissions and links
- Timestamps
- File IO
- Copy and move
- Temporary directories
local fs = require("ward.fs")
4.1 Existence and type checks
fs.is_exists(path) -> booleanfs.is_dir(path) -> booleanfs.is_file(path) -> booleanfs.is_link(path) -> booleanfs.is_symlink(path) -> booleanfs.is_block_device(path) -> boolean(Unix)fs.is_char_device(path) -> boolean(Unix)fs.is_fifo(path) -> boolean(Unix)fs.is_socket(path) -> boolean(Unix)fs.is_executable(path) -> booleanfs.is_readable(path) -> booleanfs.is_writable(path) -> boolean
Notes:
- For files,
fs.is_readable/fs.is_writablecheck whether the file can be opened for read/write. - For directories,
fs.is_readablechecks whether the directory can be listed (read_dir), andfs.is_writablechecks whether a temporary file can be created and removed inside the directory.
Example:
if fs.is_file("./build.sh") and fs.is_executable("./build.sh") then
print("runnable")
end
Path utilities
fs.readlink(path) -> string|nilfs.realpath(path) -> string|nilfs.dirname(path) -> stringfs.basename(path) -> stringfs.join(a, b, ...) -> string
Example:
local p = fs.join("build", "out", "app.bin")
print(fs.dirname(p))
print(fs.basename(p))
fs.path` - pure path manipulation (Path userdata)
fs.path provides a Path userdata type for manipulating paths without
touching the filesystem.
It is useful for building paths safely and passing them to ward.fs APIs.
Constructors:
fs.path.new(path) -> Pathfs.path.cwd() -> Pathfs.path.join(a, b) -> Path(both arguments may be strings orPath)
Methods on Path:
Path:is_abs() -> booleanPath:normalize() -> PathPath:parts() -> table(array-like, path components)Path:split() -> (dirname: string, basename: string)Path:join(segment) -> PathPath:dirname() -> stringPath:basename() -> stringPath:extname() -> nil|stringPath:stem() -> nil|stringPath:as_string() -> string
Interoperability:
Most ward.fs functions accept either a path string or a fs.path object.
Example:
local fs = require("ward.fs")
local path = require("ward.fs.path")
local p = path.new("build/../out/app.bin"):normalize()
assert(fs.mkdir(p:dirname(), { recursive = true, force = true }).ok)
assert(fs.write(p, "hello\n").ok)
print("wrote:", tostring(p))
Directory listing and globbing
fs.list(path, opts?) -> table
Returns an array-like table of paths.
Options (opts table):
recursive(boolean, defaultfalse)depth(integer, default0) - recursion depth limit;0means unlimiteddirs(boolean, defaultfalse) - include directoriesfiles(boolean, defaultfalse) - include filesregex(string|nil) - regex filter applied to the full path string
Notes:
- If both
dirsandfilesarefalse(the default), both directories and files are included. - Ordering is OS-dependent (Ward does not currently sort results).
Examples:
-- list everything
for _, p in ipairs(fs.list(".")) do
print(p)
end
-- only files, recursive, depth-limited
local files = fs.list("src", { recursive = true, depth = 3, files = true })
fs.glob(pattern) -> table
Returns an array-like table of paths matching a glob pattern.
for _, p in ipairs(fs.glob("src/**/*.rs")) do
print(p)
end
Directories and removal
Result convention for mutating operations: most functions that change the
filesystem return a table { ok, err } where ok is a boolean and err is
a string (or nil on success). When ok is false, err is intended to be
human-readable and suitable for printing/logging.
fs.mkdir(path, opts?) -> { ok, err }
Create directory.
Options:
recursive(boolean, defaultfalse)mode(number, unix-only; default0o755)force(boolean, defaultfalse) - treat “already exists” as success
assert(fs.mkdir("build", { recursive = true, mode = 0o755 }).ok)
fs.rm(path, opts?) -> { ok, err }
Remove file or directory.
Options:
recursive(boolean, defaultfalse) - required for directoriesforce(boolean, defaultfalse) - treat missing-path as success
assert(fs.rm("build", { recursive = true, force = true }).ok)
fs.unlink(path, opts?) -> { ok, err }
Remove a file (like rm -f file).
Permissions and links
fs.chmod(path, mode) -> { ok, err }fs.chown(path, uid, gid) -> { ok, err }(Unix)fs.rename(from, to) -> { ok, err }fs.link(from, to) -> { ok, err }(hard link)fs.symlink(from, to) -> { ok, err }(symbolic link)
Timestamps
fs.touch(path, opts?) -> { ok, err }
Create file if missing and update timestamps.
Options:
recursive(boolean, defaultfalse) - create parent directories first
assert(fs.touch("logs/app.log", { recursive = true }).ok)
File IO
fs.read(path, opts?) -> bytes string
Reads a file and returns a Lua string or raw bytes.
Options:
mode("text"|"binary", default"text")
local data = fs.read("README.md")
fs.write(path, data, opts?) -> { ok, err }
Write data to a file.
Options (selected):
mode("overwrite"|"append"|"prepend"|"binary", default"overwrite")binary(boolean, defaultfalse) - convertdataas bytes
Notes:
- Ward does not automatically create parent directories; combine with
fs.mkdir(fs.dirname(path), {recursive=true}).
assert(fs.write("out.txt", "hello\n").ok)
assert(fs.write("out.txt", "more\n", { mode = "append" }).ok)
Copy and move
fs.copy(from, to, opts?) -> { ok, err }fs.move(from, to, opts?) -> { ok, err }
Notes:
fs.copyoperates on regular files; it does not copy directories.fs.moveusesrenamewhen possible. On cross-device moves it falls back to copy+remove for regular files; moving directories or symlinks across devices is currently unsupported.
Temporary directories
fs.tempdir(prefix?) -> string
Creates a temporary directory and returns its path.
local dir = fs.tempdir("ward-")
print("tmp:", dir)