Documentation channel: current development main at compiler checkpoint 1d7e15e. The latest tagged release is v0.0.3; pages identify APIs that are not yet released.

Filesystem & environment

Strut's standard library provides filesystem operations, environment variables, clocks, and sleeping. Process execution now has a dedicated processes page covering current-main cancellation and lifecycle ownership.

Read environment variables

env() returns a nullable string because a variable may not exist. Use ?? when a default is appropriate.

home := env("HOME") ?? "";
print(home);

Set and remove environment variables

Mutating the current process environment can fail and uses the checked EnvironmentError contract.

function main() -> int : EnvironmentError {
    set_env("STRUT_MODE", "development");
    print(env("STRUT_MODE") ?? "missing");
    unset_env("STRUT_MODE");
    return 0;
}

Clocks and durations

now_ms() is monotonic and is suitable for measuring elapsed time. unix_ms() reports milliseconds since the Unix epoch. sleep_ms() pauses the current thread.

before := now_ms();
sleep_ms(25);
after := now_ms();
print(after - before);

Filesystem

Filesystem operations live in the explicit <filesystem> standard module and use checked FilesystemError failures.

include <filesystem>;

make_dir("build/assets");
copy("logo.png", "build/assets/logo.png");
move("old.txt", "archive/old.txt");
remove("scratch.txt");
remove_all("tmp");

Bulk paths

copy, move, and remove accept compatible iterable collections of string paths. A collection plus one destination copies or moves every source into that existing directory. Two ordered collections perform pairwise mapping and must have equal lengths; unordered sets are rejected for pairwise operations.

include <filesystem>;

copy(["a.txt", "b.txt"], "backup");
move(["one.log", "two.log"], "archive");
remove(["a.tmp", "b.tmp"]);
include <filesystem>;
include <list>;

function main() -> int : FilesystemError {
    list<string> sources;
    sources.push("draft.md");
    sources.push("notes.md");
    string[] destinations := ["archive/draft.md", "archive/notes.md"];
    copy(sources, destinations);
    return 0;
}

Wildcards

Source operands support portable Strut-side *, ?, and recursive ** expansion. Destination paths never expand wildcards. Wildcard copy/move requires an existing destination directory; an unmatched copy/move is an error, while unmatched removal is a no-op.

copy("assets/*.png", "public/images");
move("logs/*.log", "archive");
remove("build/*.o");
remove_all("tmp/**");
copy(["css/*.css", "js/*.js"], "dist");

Metadata and traversal

ls(root) returns names directly below root. walk(root) returns recursive paths relative to root; pass join_path(root, entry) to metadata or IO operations.

print(exists("data.txt"));
print(is_file("data.txt"));
print(is_dir("assets"));
print(file_size("data.txt"));
print(modified("data.txt"));

entries := ls("assets");
all_entries := walk("assets");
first_path := join_path("assets", all_entries[0]);

Path operations

path := join_path("assets", "images", "logo.png");
print(absolute(path));
print(canonical(path));
print(parent(path));
print(filename(path));
print(extension(path));
print(stem(path));

Current directory

before := cwd();
cd("workspace");
print(cwd());
cd(before);

Removal semantics

remove() removes a file or empty directory. Recursive deletion is deliberately explicit through remove_all().